DPsim
Loading...
Searching...
No Matches
Logger.cpp
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <iomanip>
10#include <memory>
11
12#include <spdlog/sinks/null_sink.h>
13#include <spdlog/sinks/stdout_color_sinks.h>
14
15#include <dpsim-models/Filesystem.h>
16#include <dpsim-models/Logger.h>
17
18using namespace CPS;
19
20void Logger::setLogLevel(std::shared_ptr<spdlog::logger> logger,
21 Logger::Level level) {
22 logger->set_level(level);
23}
24
25void Logger::setLogPattern(std::shared_ptr<spdlog::logger> logger,
26 std::string pattern) {
27 logger->set_pattern(pattern);
28}
29
30// #### to string methods ####
31String Logger::matrixToString(const Matrix &mat) {
32 std::stringstream ss;
33 ss << std::scientific << "\n" << mat;
34 return ss.str();
35}
36
37String Logger::matrixCompToString(const MatrixComp &mat) {
38 std::stringstream ss;
39 ss << std::scientific << "\n" << mat;
40 return ss.str();
41}
42
43String Logger::sparseMatrixToString(const SparseMatrix &mat) {
44 return matrixToString(Matrix(mat));
45}
46
47String Logger::sparseMatrixCompToString(const SparseMatrixComp &mat) {
48 return matrixCompToString(MatrixComp(mat));
49}
50
51String Logger::phasorMatrixToString(const MatrixComp &mat) {
52 std::stringstream ss;
53 ss << std::scientific << Math::abs(mat) << "\n\n" << Math::phase(mat);
54 return ss.str();
55}
56
57String Logger::phasorToString(const Complex &num) {
58 std::stringstream ss;
59 ss << std::defaultfloat << Math::abs(num) << "<" << Math::phaseDeg(num);
60 return ss.str();
61}
62
63String Logger::complexToString(const Complex &num) {
64 std::stringstream ss;
65 ss << std::defaultfloat << num.real() << "+j" << num.imag();
66 return ss.str();
67}
68
69String Logger::realToString(const Real &num) {
70 std::stringstream ss;
71 ss << std::defaultfloat << num;
72 return ss.str();
73}
74
75String Logger::prefix() {
76 char *p = getenv("CPS_LOG_PREFIX");
77
78 return p ? p : "";
79}
80
81String Logger::logDir() {
82 char *p = getenv("CPS_LOG_DIR");
83
84 return p ? p : "logs";
85}
86
88void Logger::setLogDir(String path) {
89#ifdef __linux__
90 setenv("CPS_LOG_DIR", path.c_str(), 1);
91#elif defined(_WIN32)
92 String var = "CPS_LOG_DIR=" + path;
93 _putenv(var.c_str());
94#endif
95}
96
97String Logger::getCSVColumnNames(std::vector<String> names) {
98 std::stringstream ss;
99 ss << std::right << std::setw(14) << "time";
100 for (auto name : names) {
101 ss << ", " << std::right << std::setw(13) << name;
102 }
103 ss << '\n';
104
105 return ss.str();
106}
107
108String Logger::getCSVLineFromData(Real time, Real data) {
109 std::stringstream ss;
110 ss << std::scientific << std::right << std::setw(14) << time;
111 ss << ", " << std::right << std::setw(13) << data;
112 ss << '\n';
113
114 return ss.str();
115}
116
117String Logger::getCSVLineFromData(Real time, const Matrix &data) {
118 std::stringstream ss;
119 ss << std::scientific << std::right << std::setw(14) << time;
120 for (Int i = 0; i < data.rows(); i++) {
121 ss << ", " << std::right << std::setw(13) << data(i, 0);
122 }
123 ss << '\n';
124
125 return ss.str();
126}
127
128String Logger::getCSVLineFromData(Real time, const MatrixComp &data) {
129 std::stringstream ss;
130 ss << std::scientific << std::right << std::setw(14) << time;
131 for (Int i = 0; i < data.rows(); i++) {
132 ss << ", " << std::right << std::setw(13) << data(i, 0);
133 }
134 ss << '\n';
135
136 return ss.str();
137}
138
139Logger::Log Logger::get(const std::string &name, Level filelevel,
140 Level clilevel) {
141 Logger::Log logger = spdlog::get(name);
142
143 if (!logger) {
144 logger = create(name, filelevel, clilevel);
145 }
146
147 return logger;
148}
149
150Logger::Log Logger::create(const std::string &name, Level filelevel,
151 Level clilevel) {
152 String logDir = Logger::logDir();
153 String filename = logDir + "/" + name + ".log";
154 std::vector<spdlog::sink_ptr> sinks;
155 Logger::Log ret;
156
157 // Create log folder if it does not exist
158 fs::path p = filename;
159 if (p.has_parent_path() && !fs::exists(p.parent_path()))
160 fs::create_directories(p.parent_path());
161
162 if (clilevel != Logger::Level::off) {
163 auto console_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
164 console_sink->set_level(clilevel);
165 console_sink->set_pattern(
166 fmt::format("{}[%T.%f %n %^%l%$] %v", CPS::Logger::prefix()));
167 sinks.push_back(console_sink);
168 }
169
170 if (filelevel != Logger::Level::off) {
171 auto file_sink =
172 std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
173 file_sink->set_level(filelevel);
174 file_sink->set_pattern(prefix() + "[%L] %v");
175 sinks.push_back(file_sink);
176 }
177
178 if (filelevel == Logger::Level::off && clilevel == Logger::Level::off) {
179 ret = spdlog::create<spdlog::sinks::null_sink_st>(name);
180 } else {
181 ret = std::make_shared<spdlog::logger>(name, begin(sinks), end(sinks));
182 }
183
184 return ret;
185}
static void setLogDir(String path)
Set env variable CPS_LOG_DIR and overwrite.
Definition Logger.cpp:88