Line data Source code
1 : /*
2 : * StandardStreamOutput.cxx
3 : * ers
4 : *
5 : * Created by Serguei Kolos on 02.08.07.
6 : * Copyright 2007 CERN. All rights reserved.
7 : *
8 : */
9 : #include <iomanip>
10 :
11 : #include <ers/Issue.hpp>
12 : #include <ers/StandardStreamOutput.hpp>
13 : #include <ers/Severity.hpp>
14 : #include <ers/internal/Util.hpp>
15 :
16 : #include <boost/algorithm/string.hpp>
17 :
18 : #define FIELD_SEPARATOR "\n\t"
19 :
20 : namespace
21 : {
22 73 : std::function<std::string( const ers::Issue & issue )> getTimeFormatter()
23 : {
24 73 : static std::string format = ers::read_from_environment(
25 146 : "DUNEDAQ_ERS_TIMESTAMP_FORMAT", "%Y-%b-%d %H:%M:%S");
26 :
27 73 : static const std::string precision = ers::read_from_environment(
28 146 : "DUNEDAQ_ERS_TIMESTAMP_PRECISION", "MILLI");
29 :
30 73 : static const bool isUTC = ::getenv("DUNEDAQ_ERS_TIMESTAMP_UTC");
31 :
32 73 : if ( boost::algorithm::ifind_first(precision, "NANO") ) {
33 0 : return [](const ers::Issue & issue){
34 0 : return issue.time<std::chrono::nanoseconds>(format, isUTC);
35 0 : };
36 : }
37 :
38 73 : if ( boost::algorithm::ifind_first(precision, "MICRO") ) {
39 0 : return [](const ers::Issue & issue){
40 0 : return issue.time<std::chrono::microseconds>(format, isUTC);
41 0 : };
42 : }
43 :
44 73 : if ( boost::algorithm::ifind_first(precision, "MILLI") ) {
45 73 : return [](const ers::Issue & issue){
46 1023 : return issue.time<std::chrono::milliseconds>(format, isUTC);
47 73 : };
48 : }
49 :
50 0 : return [](const ers::Issue & issue) {
51 0 : return issue.time(format, isUTC);
52 0 : };
53 : }
54 :
55 : const auto formatted_time = getTimeFormatter();
56 : }
57 :
58 : std::ostream &
59 1019 : ers::StandardStreamOutput::println( std::ostream & out, const Issue & issue, int verbosity )
60 : {
61 1019 : print( out, issue, verbosity );
62 1019 : out << std::endl;
63 1019 : return out;
64 : }
65 :
66 : std::ostream &
67 1023 : ers::StandardStreamOutput::print( std::ostream & out, const Issue & issue, int verbosity )
68 : {
69 1023 : if ( verbosity > -3 )
70 : {
71 1023 : out << formatted_time( issue ) << " ";
72 : }
73 :
74 1023 : if ( verbosity > -2 )
75 : {
76 1023 : out << ers::to_string( issue.severity() ) << " ";
77 : }
78 :
79 1023 : if ( verbosity > -1 )
80 : {
81 1023 : out << "[" << issue.context().position( verbosity ) << "] ";
82 : }
83 :
84 1023 : out << issue.message();
85 :
86 1023 : if ( verbosity > 1 )
87 : {
88 0 : out << FIELD_SEPARATOR << "Parameters = ";
89 0 : for ( ers::string_map::const_iterator it = issue.parameters().begin(); it != issue.parameters().end(); ++it )
90 : {
91 0 : out << "'" << it->first << "=" << it->second << "' ";
92 : }
93 :
94 0 : out << FIELD_SEPARATOR << "Qualifiers = ";
95 0 : for ( std::vector<std::string>::const_iterator it = issue.qualifiers().begin(); it != issue.qualifiers().end(); ++it )
96 : {
97 0 : out << "'" << *it << "' ";
98 : }
99 : }
100 :
101 0 : if ( verbosity > 2 )
102 : {
103 0 : out << FIELD_SEPARATOR << "host = " << issue.context().host_name()
104 0 : << FIELD_SEPARATOR << "user = " << issue.context().user_name()
105 0 : << " (" << issue.context().user_id() << ")"
106 0 : << FIELD_SEPARATOR << "process id = " << issue.context().process_id()
107 0 : << FIELD_SEPARATOR << "thread id = " << issue.context().thread_id()
108 0 : << FIELD_SEPARATOR << "process wd = " << issue.context().cwd();
109 : }
110 :
111 0 : if ( verbosity > 3 )
112 : {
113 0 : std::ios_base::fmtflags flags( out.flags() );
114 :
115 0 : out << std::left;
116 0 : std::vector<std::string> stack = issue.context().stack();
117 0 : out << FIELD_SEPARATOR << "stack trace of the crashing thread:";
118 0 : for( size_t i = 0; i < stack.size(); i++ )
119 : {
120 0 : out << FIELD_SEPARATOR << " #" << std::setw(3) << i << stack[i];
121 : }
122 : // restore the original state
123 0 : out.flags( flags );
124 0 : }
125 :
126 1023 : if ( issue.cause() )
127 : {
128 4 : out << FIELD_SEPARATOR << "was caused by: " << *issue.cause();
129 : }
130 :
131 1023 : return out;
132 : }
|