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