/src/dcmtk/oflog/libsrc/log4judp.cc
Line | Count | Source |
1 | | // Module: Log4CPLUS |
2 | | // File: log4judpappender.cxx |
3 | | // Created: 7/2012 |
4 | | // Author: Siva Chandran P |
5 | | // |
6 | | // |
7 | | // Copyright 2012 Siva Chandran P |
8 | | // |
9 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
10 | | // you may not use this file except in compliance with the License. |
11 | | // You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software |
16 | | // distributed under the License is distributed on an "AS IS" BASIS, |
17 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
18 | | // See the License for the specific language governing permissions and |
19 | | // limitations under the License. |
20 | | |
21 | | #include "dcmtk/oflog/log4judp.h" |
22 | | #include "dcmtk/oflog/layout.h" |
23 | | #include "dcmtk/oflog/streams.h" |
24 | | #include "dcmtk/oflog/logmacro.h" |
25 | | #include "dcmtk/oflog/helpers/loglog.h" |
26 | | #include "dcmtk/oflog/helpers/property.h" |
27 | | #include "dcmtk/oflog/spi/logevent.h" |
28 | | #include "dcmtk/oflog/internal/internal.h" |
29 | | #include "dcmtk/oflog/thread/syncpub.h" |
30 | | #include <iomanip> |
31 | | #include <cstring> |
32 | | #if defined (DCMTK_OFLOG_UNICODE) |
33 | | #include <cwctype> |
34 | | #else |
35 | | #include <cctype> |
36 | | #endif |
37 | | |
38 | | |
39 | | namespace dcmtk |
40 | | { |
41 | | namespace log4cplus |
42 | | { |
43 | | |
44 | | namespace |
45 | | { |
46 | | |
47 | | |
48 | | static inline bool |
49 | | is_control (tchar ch) |
50 | 0 | { |
51 | | #if defined (DCMTK_OFLOG_UNICODE) |
52 | | return !! STD_NAMESPACE iswcntrl (STD_NAMESPACE char_traits<tchar>::to_int_type (ch)); |
53 | | #else |
54 | 0 | return !! STD_NAMESPACE iscntrl (STD_NAMESPACE char_traits<tchar>::to_int_type (ch)); |
55 | 0 | #endif |
56 | 0 | } |
57 | | |
58 | | |
59 | | //! Outputs str with reserved XML characters escaped. |
60 | | static |
61 | | void |
62 | | output_xml_escaped (tostream & os, tstring const & str) |
63 | 0 | { |
64 | 0 | for (tstring::const_iterator it = str.begin (); it != str.end (); ++it) |
65 | 0 | { |
66 | 0 | tchar const & ch = *it; |
67 | 0 | switch (ch) |
68 | 0 | { |
69 | 0 | case DCMTK_LOG4CPLUS_TEXT ('<'): |
70 | 0 | os << DCMTK_LOG4CPLUS_TEXT ("<"); |
71 | 0 | break; |
72 | | |
73 | 0 | case DCMTK_LOG4CPLUS_TEXT ('>'): |
74 | 0 | os << DCMTK_LOG4CPLUS_TEXT (">"); |
75 | 0 | break; |
76 | | |
77 | 0 | case DCMTK_LOG4CPLUS_TEXT ('&'): |
78 | 0 | os << DCMTK_LOG4CPLUS_TEXT ("&"); |
79 | 0 | break; |
80 | | |
81 | 0 | case DCMTK_LOG4CPLUS_TEXT ('\''): |
82 | 0 | os << DCMTK_LOG4CPLUS_TEXT ("'"); |
83 | 0 | break; |
84 | | |
85 | 0 | case DCMTK_LOG4CPLUS_TEXT ('"'): |
86 | 0 | os << DCMTK_LOG4CPLUS_TEXT ("""); |
87 | 0 | break; |
88 | | |
89 | 0 | default: |
90 | 0 | if (is_control (ch)) |
91 | 0 | { |
92 | 0 | tchar const prev_fill = os.fill (); |
93 | 0 | STD_NAMESPACE ios_base::fmtflags const prev_flags = os.flags (); |
94 | 0 | os.flags (STD_NAMESPACE ios_base::hex | STD_NAMESPACE ios_base::right); |
95 | 0 | os.fill (DCMTK_LOG4CPLUS_TEXT ('0')); |
96 | |
|
97 | 0 | os << STD_NAMESPACE setw (0) << DCMTK_LOG4CPLUS_TEXT ("&#x") |
98 | 0 | << STD_NAMESPACE setw (2) << STD_NAMESPACE char_traits<tchar>::to_int_type (ch) |
99 | 0 | << STD_NAMESPACE setw (0) << DCMTK_LOG4CPLUS_TEXT (";"); |
100 | |
|
101 | 0 | os.fill (prev_fill); |
102 | 0 | os.flags (prev_flags); |
103 | 0 | } |
104 | 0 | else |
105 | 0 | os.put (ch); |
106 | 0 | } |
107 | 0 | } |
108 | 0 | } |
109 | | |
110 | | |
111 | | //! Helper manipulator like class for escaped XML output. |
112 | | struct outputXMLEscaped |
113 | | { |
114 | | outputXMLEscaped (tstring const & s) |
115 | 0 | : str (s) |
116 | 0 | { } |
117 | | |
118 | | tstring const & str; |
119 | | }; |
120 | | |
121 | | |
122 | | //! Overload stream insertion for outputXMLEscaped. |
123 | | static |
124 | | tostream & |
125 | | operator << (tostream & os, outputXMLEscaped const & x) |
126 | 0 | { |
127 | 0 | output_xml_escaped (os, x.str); |
128 | 0 | return os; |
129 | 0 | } |
130 | | |
131 | | |
132 | | } // namespace |
133 | | |
134 | | |
135 | | ////////////////////////////////////////////////////////////////////////////// |
136 | | // Log4jUdpAppender ctors and dtor |
137 | | ////////////////////////////////////////////////////////////////////////////// |
138 | | |
139 | | Log4jUdpAppender::Log4jUdpAppender(const tstring& host_, int port_) |
140 | 0 | : socket() |
141 | 0 | , host(host_) |
142 | 0 | , port(port_) |
143 | 0 | { |
144 | 0 | layout.reset (new PatternLayout (DCMTK_LOG4CPLUS_TEXT ("%m"))); |
145 | 0 | openSocket(); |
146 | 0 | } Unexecuted instantiation: dcmtk::log4cplus::Log4jUdpAppender::Log4jUdpAppender(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) Unexecuted instantiation: dcmtk::log4cplus::Log4jUdpAppender::Log4jUdpAppender(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) |
147 | | |
148 | | |
149 | | |
150 | | Log4jUdpAppender::Log4jUdpAppender(const helpers::Properties & properties) |
151 | 0 | : Appender(properties) |
152 | 0 | , socket() |
153 | 0 | , host() |
154 | 0 | , port(5000) |
155 | 0 | { |
156 | 0 | host = properties.getProperty( DCMTK_LOG4CPLUS_TEXT("host"), |
157 | 0 | DCMTK_LOG4CPLUS_TEXT ("localhost") ); |
158 | 0 | properties.getInt (port, DCMTK_LOG4CPLUS_TEXT ("port")); |
159 | |
|
160 | 0 | openSocket(); |
161 | 0 | } Unexecuted instantiation: dcmtk::log4cplus::Log4jUdpAppender::Log4jUdpAppender(dcmtk::log4cplus::helpers::Properties const&) Unexecuted instantiation: dcmtk::log4cplus::Log4jUdpAppender::Log4jUdpAppender(dcmtk::log4cplus::helpers::Properties const&) |
162 | | |
163 | | |
164 | | |
165 | | Log4jUdpAppender::~Log4jUdpAppender() |
166 | 0 | { |
167 | 0 | destructorImpl(); |
168 | 0 | } |
169 | | |
170 | | |
171 | | |
172 | | ////////////////////////////////////////////////////////////////////////////// |
173 | | // Log4jUdpAppender public methods |
174 | | ////////////////////////////////////////////////////////////////////////////// |
175 | | |
176 | | void |
177 | | Log4jUdpAppender::close() |
178 | 0 | { |
179 | 0 | helpers::getLogLog().debug( |
180 | 0 | DCMTK_LOG4CPLUS_TEXT("Entering Log4jUdpAppender::close()...")); |
181 | |
|
182 | 0 | socket.close(); |
183 | 0 | closed = true; |
184 | 0 | } |
185 | | |
186 | | |
187 | | |
188 | | ////////////////////////////////////////////////////////////////////////////// |
189 | | // Log4jUdpAppender protected methods |
190 | | ////////////////////////////////////////////////////////////////////////////// |
191 | | |
192 | | void |
193 | | Log4jUdpAppender::openSocket() |
194 | 0 | { |
195 | 0 | if(!socket.isOpen()) { |
196 | 0 | socket = helpers::Socket(host, OFstatic_cast(unsigned short, port), true); |
197 | 0 | } |
198 | 0 | } |
199 | | |
200 | | void |
201 | | Log4jUdpAppender::append(const spi::InternalLoggingEvent& event) |
202 | 0 | { |
203 | 0 | if(!socket.isOpen()) { |
204 | 0 | openSocket(); |
205 | 0 | if(!socket.isOpen()) { |
206 | 0 | helpers::getLogLog().error( |
207 | 0 | DCMTK_LOG4CPLUS_TEXT("Log4jUdpAppender::append()- Cannot connect to server")); |
208 | 0 | return; |
209 | 0 | } |
210 | 0 | } |
211 | | |
212 | 0 | tstring & str = formatEvent (event); |
213 | |
|
214 | 0 | internal::appender_sratch_pad & appender_sp |
215 | 0 | = internal::get_appender_sp (); |
216 | 0 | tostringstream & buffer = appender_sp.oss; |
217 | 0 | detail::clear_tostringstream (buffer); |
218 | |
|
219 | 0 | buffer << DCMTK_LOG4CPLUS_TEXT("<log4j:event logger=\"") |
220 | 0 | << outputXMLEscaped (event.getLoggerName()) |
221 | 0 | << DCMTK_LOG4CPLUS_TEXT("\" level=\"") |
222 | | // TODO: Some escaping of special characters is needed here. |
223 | 0 | << outputXMLEscaped (getLogLevelManager().toString(event.getLogLevel())) |
224 | 0 | << DCMTK_LOG4CPLUS_TEXT("\" timestamp=\"") |
225 | 0 | << event.getTimestamp().getFormattedTime(DCMTK_LOG4CPLUS_TEXT("%s%q")) |
226 | 0 | << DCMTK_LOG4CPLUS_TEXT("\" thread=\"") << event.getThread() |
227 | 0 | << DCMTK_LOG4CPLUS_TEXT("\">") |
228 | |
|
229 | 0 | << DCMTK_LOG4CPLUS_TEXT("<log4j:message>") |
230 | | // TODO: Some escaping of special characters is needed here. |
231 | 0 | << outputXMLEscaped (str) |
232 | 0 | << DCMTK_LOG4CPLUS_TEXT("</log4j:message>") |
233 | |
|
234 | 0 | << DCMTK_LOG4CPLUS_TEXT("<log4j:NDC>") |
235 | | // TODO: Some escaping of special characters is needed here. |
236 | 0 | << outputXMLEscaped (event.getNDC()) |
237 | 0 | << DCMTK_LOG4CPLUS_TEXT("</log4j:NDC>") |
238 | |
|
239 | 0 | << DCMTK_LOG4CPLUS_TEXT("<log4j:locationInfo class=\"\" file=\"") |
240 | | // TODO: Some escaping of special characters is needed here. |
241 | 0 | << outputXMLEscaped (event.getFile()) |
242 | 0 | << DCMTK_LOG4CPLUS_TEXT("\" method=\"") |
243 | 0 | << outputXMLEscaped (event.getFunction()) |
244 | 0 | << DCMTK_LOG4CPLUS_TEXT("\" line=\"") |
245 | 0 | << event.getLine() |
246 | 0 | << DCMTK_LOG4CPLUS_TEXT("\"/>") |
247 | 0 | << DCMTK_LOG4CPLUS_TEXT("</log4j:event>"); |
248 | |
|
249 | 0 | DCMTK_LOG4CPLUS_TSTRING_TO_STRING (buffer.str ()).swap (appender_sp.chstr); |
250 | |
|
251 | 0 | bool ret = socket.write(appender_sp.chstr); |
252 | 0 | if (!ret) |
253 | 0 | { |
254 | 0 | helpers::getLogLog().error( |
255 | 0 | DCMTK_LOG4CPLUS_TEXT( |
256 | 0 | "Log4jUdpAppender::append()- Cannot write to server")); |
257 | 0 | } |
258 | 0 | } |
259 | | |
260 | | } // namespace log4cplus |
261 | | } // end namespace dcmtk |