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

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