source: trunk/FACT++/src/showlog.cc@ 17676

Last change on this file since 17676 was 16968, checked in by tbretz, 11 years ago
Added a possibility to strip color codes.
File size: 6.1 KB
Line 
1#include <boost/regex.hpp>
2
3#include "Time.h"
4#include "tools.h"
5#include "WindowLog.h"
6#include "Configuration.h"
7
8
9using namespace std;
10
11// ------------------------------------------------------------------------
12
13void SetupConfiguration(Configuration &conf)
14{
15 po::options_description control("Showlog");
16 control.add_options()
17 ("file,f", vars<string>(), "File names of log-files to be read.")
18 ("begin,b", var<string>(), "Start time to be displayed (e.g. 20:00:12)")
19 ("end,e", var<string>(), "End time to be displayed (e.g. 21:00:13)")
20 ("verbose,v", var<int16_t>()->implicit_value(true)->default_value(8), "Verbosity level (0:only fatal errors, 8:everything)")
21 ("color,c", po_switch(), "Process a file which already contains color codes")
22 ("strip,s", po_switch(), "Strip color codes completely")
23 ;
24
25 po::positional_options_description p;
26 p.add("file", -1); // The first positional options
27
28 conf.AddOptions(control);
29 conf.SetArgumentPositions(p);
30}
31
32void PrintUsage()
33{
34 cout <<
35 "showlog - Log file converter\n"
36 "\n"
37 "This tool can be used to convert the log-files written by the\n"
38 "datalogger back to colored output, limit the displayed time\n"
39 "range and limit the displayed severity of the messages.\n"
40 "Note that this tool will not work by default on logs containing\n"
41 "already colored output as the logs directly written by the programs.\n"
42 "Use -c or --color to process color coded files.\n"
43 "\n"
44 "The default is to read from stdin if no filoename as given. If, as "
45 "a filename, just a number between 2000000 and 21000000 is given, "
46 "e.g. 20111016 a log with the name /fact/aux/2011/10/16/20111016.log "
47 "is read.\n"
48 "\n"
49 "Usage: showlog [-c] [-vN] [-b start] [-e end] [file1 ...]\n"
50 " or: showlog [-c] [-vN] [-b start] [-e end] YYYYMMDD\n";
51 cout << endl;
52}
53
54void PrintHelp()
55{
56 cout <<
57 "\n"
58 "Examples:\n"
59 " cat temperature.log | showlog -c -v2\n"
60 " showlog -c temperature.log -v2\n"
61 " cat 20130909.log | showlog -v2\n"
62 " showlog 20130909.log -v2\n"
63 "\n";
64 cout << endl;
65}
66
67
68void showlog(string fname, const Time &tbeg, const Time &tend, int16_t severity, bool color, bool strip)
69{
70 // Alternatives
71 // \x1B\[[0-9;]*[mK]
72 // \x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]
73 // \x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]
74 const boost::regex reg("\x1B\[([0-9]{1,3}(;[0-9]{1,3})?[a-zA-Z]");
75
76 const uint32_t night = atoi(fname.c_str());
77 if (night>20000000 && night<21000000 &&to_string(night)==fname)
78 fname = Tools::Form("/fact/aux/%04d/%02d/%02d/%d.log",
79 night/10000, (night/100)%100, night%100, night);
80
81 if (!fname.empty())
82 cerr << "Reading " << fname << endl;
83
84 ifstream fin(fname.empty() ? "/dev/stdin" : fname.c_str());
85 if (!fin)
86 throw runtime_error(strerror(errno));
87
88 string buffer;
89
90 WindowLog log;
91
92 Time tprev;
93
94 while (getline(fin, buffer, '\n'))
95 {
96 if (color || strip)
97 buffer = boost::regex_replace(buffer, reg, "");
98
99 if (buffer.size()==0)
100 continue;
101
102 if (buffer.size()>18)
103 {
104 const string tm = buffer.substr(4, 15);
105
106 const Time t("1970-01-01 "+tm);
107
108 if (tbeg.IsValid() && !tend.IsValid() && t<tbeg)
109 continue;
110
111 if (tend.IsValid() && !tbeg.IsValid() && t>tend)
112 continue;
113
114 if (tbeg.IsValid() && tend.IsValid())
115 {
116 if (tend>tbeg)
117 {
118 if (t<tbeg)
119 continue;
120 if (t>tend)
121 continue;
122 }
123 else
124 {
125 if (t>tbeg)
126 continue;
127 if (t<tend)
128 continue;
129 }
130 }
131 }
132
133 if (buffer.size()>1 && !strip)
134 {
135 int16_t lvl = -1;
136 switch (buffer[1])
137 {
138 case ' ': lvl = 7; break; // kDebug
139 case '#': lvl = 6; break; // kComment
140 case '-': lvl = 5; break; // kMessage
141 case '>': lvl = 4; break;
142 case 'I': lvl = 3; break; // kInfo
143 case 'W': lvl = 2; break; // kWarn
144 case 'E': lvl = 1; break; // kError/kAlarm
145 case '!': lvl = 0; break; // kFatal
146 }
147
148 if (lvl>severity)
149 continue;
150
151 switch (buffer[1])
152 {
153 case ' ': log << kBlue; break; // kDebug
154 case '#': log << kDefault; break; // kComment
155 case '-': log << kDefault; break; // kMessage
156 case '>': log << kBold; break;
157 case 'I': log << kGreen; break; // kInfo
158 case 'W': log << kYellow; break; // kWarn
159 case 'E': log << kRed; break; // kError/kAlarm
160 case '!': log << kRed << kBlink; break; // kFatal
161 }
162 }
163
164 (strip?cout:log) << buffer << endl;
165 }
166}
167
168int main(int argc, const char* argv[])
169{
170 Configuration conf(argv[0]);
171 conf.SetPrintUsage(PrintUsage);
172 SetupConfiguration(conf);
173
174 if (!conf.DoParse(argc, argv, PrintHelp))
175 return 127;
176
177 const vector<string> files = conf.Vec<string>("file");
178
179 Time tbeg(Time::none);
180 Time tend(Time::none);
181
182 if (conf.Has("begin"))
183 {
184 std::stringstream stream;
185 stream << "1970-01-01 " << conf.Get<string>("begin");
186 stream >> Time::iso >> tbeg;
187 }
188
189 if (conf.Has("end"))
190 {
191 std::stringstream stream;
192 stream << "1970-01-01 " << conf.Get<string>("end");
193 stream >> Time::iso >> tend;
194 }
195
196 if (files.size()==0)
197 showlog("", tbeg, tend, conf.Get<int16_t>("verbose"), conf.Get<bool>("color"), conf.Get<bool>("strip"));
198
199 for (auto it=files.begin(); it!=files.end(); it++)
200 showlog(*it, tbeg, tend, conf.Get<int16_t>("verbose"), conf.Get<bool>("color"), conf.Get<bool>("strip"));
201
202 return 0;
203}
Note: See TracBrowser for help on using the repository browser.