Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
* Logging.cc
*
* Created on: Apr 3, 2018
* Author: zenker
*/
#include <string>
#include <sstream>
#include <ostream>
#include <vector>
#include "boost/date_time/posix_time/posix_time.hpp"
#include "Logging.h"
using namespace logging;
std::ostream& logging::operator<<(std::ostream &os,const LogLevel &level){
switch(level){
case LogLevel::DEBUG:
os << "DEBUG::";
break;
case LogLevel::INFO:
os << "INFO::";
break;
case LogLevel::WARNING:
os << "WARNING::";
break;
case LogLevel::ERROR:
os << "ERROR::";
break;
default:
break;
}
return os;
}
std::string logging::getTime(){
std::string str;
str.append(boost::posix_time::to_simple_string(boost::posix_time::microsec_clock::local_time()) + " ");
str.append(" -> ");
return str;
}
Logger::Logger(ctk::Module* module){
message.reset(new ctk::ScalarOutput<std::string>{module, "message", "", "Message of the module to the logging System",
{ "Logging", "OneWire", module->getName() } });
messageLevel.reset(new ctk::ScalarOutput<uint>{module, "messageLevel", "", "Logging level of the message",
{ "Logging", "OneWire", module->getName() } });
}
void Logger::sendMessage(const std::string &msg, const logging::LogLevel &level){
if(message->isInitialised()){
while(!msg_buffer.empty()){
*message = msg_buffer.front().first;
*messageLevel = msg_buffer.front().second;
message->write();
messageLevel->write();
msg_buffer.pop();
}
*message = msg + "\n";
*messageLevel = level;
message->write();
messageLevel->write();
} else {
// only use the buffer until ctk initialized the process variables
msg_buffer.push(std::make_pair(msg + "\n", level));
}
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
}
void LoggingModule::broadcastMessage(std::string msg, bool isError){
if(msg.back() != '\n'){
msg.append("\n");
}
std::string tmpLog = (std::string)logTail;
if( tailLength == 0 && messageCounter > 20){
messageCounter--;
tmpLog = tmpLog.substr(tmpLog.find_first_of("\n")+1, tmpLog.length());
} else if (tailLength > 0){
while(messageCounter >= tailLength){
messageCounter--;
tmpLog = tmpLog.substr(tmpLog.find_first_of("\n")+1, tmpLog.length());
}
}
if(targetStream == 0 || targetStream == 2){
if(isError)
std::cerr << msg;
else
std::cout << msg;
}
if(targetStream == 0 || targetStream == 1){
if(file->is_open()){
(*file) << msg.c_str();
file->flush();
}
}
tmpLog.append(msg);
messageCounter++;
logTail = tmpLog;
logTail.write();
}
void LoggingModule::mainLoop(){
file.reset(new std::ofstream());
messageCounter = 0;
std::stringstream greeter;
greeter << getName() << " " << getTime() << "There are " << msg_list.size() << " modules registered for logging:" << std::endl;
broadcastMessage(greeter.str());
for(auto &module : msg_list){
broadcastMessage(std::string("\t - ") + module.first);
}
Martin Christoph Hierholzer
committed
auto group = readAnyGroup();
while(1){
auto id = group.readAny();
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
auto sender = UpdatePair(id);
if(targetStream == 3)
continue;
LogLevel level = static_cast<LogLevel>((uint)sender->second.second);
LogLevel setLevel = static_cast<LogLevel>((uint)logLevel);
std::stringstream ss;
ss << level << getName() << "/" << sender->first << " " << getTime() << (std::string)sender->second.first;
if(targetStream == 0 || targetStream == 1){
if(!((std::string)logFile).empty() && !file->is_open()){
file->open((std::string)logFile, std::ofstream::out | std::ofstream::app);
std::stringstream ss_file;
if(!file->is_open() && setLevel <= LogLevel::ERROR){
ss_file << LogLevel::ERROR << getName() << " " << getTime() << "Failed to open log file for writing: " << (std::string)logFile << std::endl;
broadcastMessage(ss_file.str(), true);
} else if (file->is_open() && setLevel <= LogLevel::INFO){
ss_file << LogLevel::INFO << getName() << " " << getTime() << "Opened log file for writing: " << (std::string)logFile << std::endl;
broadcastMessage(ss_file.str());
}
}
}
if(level >= setLevel){
if(level < LogLevel::ERROR)
broadcastMessage(ss.str());
else
broadcastMessage(ss.str(), true);
}
}
}
void LoggingModule::addSource(Logger *logger){
auto acc = getAccessorPair(logger->message->getOwner()->getName());
*logger->message.get() >> acc.first;
*logger->messageLevel.get() >> acc.second;
}
std::pair<ctk::VariableNetworkNode,ctk::VariableNetworkNode> LoggingModule::getAccessorPair(const std::string &sender) {
if(msg_list.count(sender) == 0){
msg_list.emplace(std::piecewise_construct, std::make_tuple(sender),std::forward_as_tuple(
std::piecewise_construct,
std::forward_as_tuple(ctk::ScalarPushInput<std::string>{this, sender + "Msg", "", ""}),
std::forward_as_tuple(ctk::ScalarPushInput<uint>{this, sender + "MsgLevel", "", ""})));
} else {
throw ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalVariableNetwork>("Cannot add logging for module "+sender+
" since logging was already added for this module.");
}
return msg_list[sender];
}
std::map<std::string, Message>::iterator LoggingModule::UpdatePair(const mtca4u::TransferElementID &id){
for(auto it = msg_list.begin(), iend = msg_list.end(); it != iend; it++){
if(it->second.first.getId() == id){
it->second.second.read();
return it;
}
if(it->second.second.getId() == id){
it->second.first.read();
return it;
}
}
throw ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalVariableNetwork>("Cannot find element id"
"when updating logging variables.");
}
void LoggingModule::terminate(){
if((file.get() != nullptr) && (file->is_open()))
file->close();
ApplicationModule::terminate();
}