Line data Source code
1 : /*
2 : * Issue.cxx
3 : * ers
4 : *
5 : * Created by Matthias Wiesmann on 26.11.04.
6 : * Modified by Serguei Kolos on 02.08.05.
7 : * Copyright 2004 CERN. All rights reserved.
8 : *
9 : */
10 :
11 : #include <csignal>
12 : #include <iomanip>
13 : #include <sstream>
14 : #include <algorithm>
15 : #include <ctime>
16 : #include <time.h>
17 :
18 : #include <ers/Issue.hpp>
19 : #include <ers/IssueFactory.hpp>
20 : #include <ers/OutputStream.hpp>
21 : #include <ers/StandardStreamOutput.hpp>
22 : #include <ers/ers.hpp>
23 : #include <ers/internal/Util.hpp>
24 :
25 : using namespace ers;
26 :
27 77 : ERS_DECLARE_ISSUE( ers, StdIssue, ERS_EMPTY, ERS_EMPTY )
28 :
29 : namespace
30 : {
31 3297 : int get_default_qualifiers( std::vector<std::string> & qualifiers )
32 : {
33 3297 : static const char * environment = ::getenv( "DUNEDAQ_ERS_QUALIFIERS" );
34 3297 : if ( environment )
35 : {
36 0 : ers::tokenize( environment, ",", qualifiers );
37 : }
38 3297 : return 1;
39 : }
40 :
41 3297 : void add_default_qualifiers( Issue & issue )
42 : {
43 3297 : static std::vector<std::string> qualifiers;
44 : // static int _unused_ = get_default_qualifiers( qualifiers );
45 3297 : get_default_qualifiers( qualifiers );
46 3297 : for ( std::vector<std::string>::const_iterator it = qualifiers.begin(); it != qualifiers.end(); ++it )
47 : {
48 0 : issue.add_qualifier( *it );
49 : }
50 3297 : }
51 : }
52 :
53 72 : Issue::Issue( const Issue & other )
54 : : std::exception( other ),
55 72 : m_cause( other.m_cause.get() ? other.m_cause->clone() : 0 ),
56 72 : m_context( other.m_context->clone() ),
57 72 : m_message( other.m_message ),
58 72 : m_qualifiers( other.m_qualifiers ),
59 72 : m_severity( other.m_severity ),
60 72 : m_time( other.m_time ),
61 144 : m_values( other.m_values )
62 72 : { ; }
63 :
64 :
65 : /** This constructor create a new issue with the given message.
66 : * \param context the context of the Issue, e.g where in the code the issue appeared
67 : * \param message the user message associated with this issue
68 : */
69 3268 : Issue::Issue( const Context & context,
70 3268 : const std::string & message )
71 3268 : : m_context( context.clone() ),
72 3268 : m_message( message ),
73 3268 : m_severity( ers::Error ),
74 9804 : m_time( system_clock::now() )
75 : {
76 3268 : add_qualifier( m_context->package_name() );
77 3268 : add_default_qualifiers( *this );
78 3268 : }
79 :
80 : /** This constructor takes another exceptions as its cause.
81 : * \param context the context of the Issue, e.g where in the code the issue appeared
82 : * \param cause the other exception that has caused this one
83 : */
84 29 : Issue::Issue( const Context & context,
85 29 : const std::exception & cause )
86 29 : : m_context( context.clone() ),
87 29 : m_severity( ers::Error ),
88 87 : m_time( system_clock::now() )
89 : {
90 29 : const Issue * issue = dynamic_cast<const Issue *>( &cause );
91 29 : m_cause.reset( issue ? issue->clone() : new StdIssue( ERS_HERE, cause.what() ) );
92 29 : add_qualifier( m_context->package_name() );
93 29 : add_default_qualifiers( *this );
94 29 : }
95 :
96 : /** This constructor takes another exceptions as its cause.
97 : * \param context the context of the Issue, e.g where in the code did the issue appear
98 : * \param message the user message associated with this issue
99 : * \param cause exception that caused the current issue
100 : */
101 0 : Issue::Issue( const Context & context,
102 : const std::string & message,
103 0 : const std::exception & cause )
104 0 : : m_context( context.clone() ),
105 0 : m_message( message ),
106 0 : m_severity( ers::Error ),
107 0 : m_time( system_clock::now() )
108 : {
109 0 : const Issue * issue = dynamic_cast<const Issue *>( &cause );
110 0 : m_cause.reset( issue ? issue->clone() : new StdIssue( ERS_HERE, cause.what() ) );
111 0 : add_qualifier( m_context->package_name() );
112 0 : add_default_qualifiers( *this );
113 0 : }
114 :
115 0 : Issue::Issue( Severity severity,
116 : const system_clock::time_point & time,
117 : const ers::Context & context,
118 : const std::string & message,
119 : const std::vector<std::string> & qualifiers,
120 : const std::map<std::string, std::string> & parameters,
121 0 : const ers::Issue * cause )
122 0 : : m_cause( cause ),
123 0 : m_context( context.clone() ),
124 0 : m_message( message ),
125 0 : m_qualifiers( qualifiers ),
126 0 : m_severity( severity ),
127 0 : m_time( time ),
128 0 : m_values( parameters )
129 0 : { ; }
130 :
131 3369 : ers::Issue::~Issue() noexcept
132 3369 : { ; }
133 :
134 : std::time_t
135 1138 : ers::Issue::time_t() const
136 : {
137 1138 : return system_clock::to_time_t(m_time);
138 : }
139 :
140 : void
141 2 : ers::Issue::get_value( const std::string & key, const char * & value ) const
142 : {
143 2 : string_map::const_iterator it = m_values.find(key);
144 2 : if ( it != m_values.end() )
145 : {
146 2 : value = it->second.c_str();
147 : }
148 : else
149 : {
150 0 : throw ers::NoValue( ERS_HERE, key );
151 : }
152 2 : }
153 :
154 : void
155 0 : ers::Issue::get_value( const std::string & key, std::string & value ) const
156 : {
157 0 : string_map::const_iterator it = m_values.find(key);
158 0 : if ( it != m_values.end() )
159 : {
160 0 : value = it->second;
161 : }
162 : else
163 : {
164 0 : throw ers::NoValue( ERS_HERE, key );
165 : }
166 0 : }
167 :
168 : /** Add a new qualifier to the qualifiers list of this issue
169 : * \param qualifier the qualifier to add
170 : */
171 : void
172 3297 : Issue::add_qualifier( const std::string & qualifier )
173 : {
174 3297 : if ( std::find( m_qualifiers.begin(), m_qualifiers.end(), qualifier ) == m_qualifiers.end() ) {
175 3297 : m_qualifiers.push_back( qualifier );
176 : }
177 3297 : }
178 :
179 : ers::Severity
180 2145 : Issue::set_severity( ers::Severity severity ) const
181 : {
182 2145 : ers::Severity old_severity = m_severity;
183 2145 : m_severity = severity;
184 2145 : return old_severity;
185 : }
186 :
187 : /** Adds the given text to the beginning of the issue's message
188 : * \param msg text to be prepended
189 : */
190 : void
191 2366 : Issue::prepend_message( const std::string & msg )
192 : {
193 2366 : m_message = msg + m_message;
194 2366 : }
195 :
196 : /** Adds the given text strings to the beginning and to the end of the issue's message
197 : * \param begin text to be prepended
198 : * \param begin text to be appended
199 : */
200 : void
201 0 : Issue::wrap_message( const std::string & begin, const std::string & end )
202 : {
203 0 : m_message = begin + m_message + end;
204 0 : }
205 :
206 : namespace ers {
207 :
208 : /** Standard streaming operator - puts the issue in human readable format into the standard out stream.
209 : * \param out the destination out stream
210 : * \param issue the Issue to be printed
211 : */
212 4 : std::ostream & operator<<( std::ostream & out, const ers::Issue & issue )
213 : {
214 4 : return StandardStreamOutput::print( out, issue, ers::verbosity_level() );
215 : }
216 : }
217 :
218 :
219 :
220 :
|