source: XMLIO_V2/external/src/POCO/Foundation/Logger.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1//
2// Logger.cpp
3//
4// $Id: //poco/1.3/Foundation/src/Logger.cpp#3 $
5//
6// Library: Foundation
7// Package: Logging
8// Module:  Logger
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include <Poco/Logger.h>
38#include <Poco/Formatter.h>
39#include <Poco/LoggingRegistry.h>
40#include <Poco/Exception.h>
41#include <Poco/NumberFormatter.h>
42
43
44namespace Poco {
45
46
47Logger::LoggerMap* Logger::_pLoggerMap = 0;
48Mutex Logger::_mapMtx;
49const std::string Logger::ROOT;
50
51
52Logger::Logger(const std::string& name, Channel* pChannel, int level): _name(name), _pChannel(pChannel), _level(level)
53{
54        if (pChannel) pChannel->duplicate();
55}
56
57
58Logger::~Logger()
59{
60        if (_pChannel) _pChannel->release();
61}
62
63
64void Logger::setChannel(Channel* pChannel)
65{
66        if (_pChannel) _pChannel->release();
67        _pChannel = pChannel;
68        if (_pChannel) _pChannel->duplicate();
69}
70
71
72Channel* Logger::getChannel() const
73{
74        return _pChannel;
75}
76
77
78void Logger::setLevel(int level)
79{
80        _level = level;
81}
82
83
84void Logger::setLevel(const std::string& level)
85{
86        if (level == "fatal")
87                setLevel(Message::PRIO_FATAL);
88        else if (level == "critical")
89                setLevel(Message::PRIO_CRITICAL);
90        else if (level == "error")
91                setLevel(Message::PRIO_ERROR);
92        else if (level == "warning")
93                setLevel(Message::PRIO_WARNING);
94        else if (level == "notice")
95                setLevel(Message::PRIO_NOTICE);
96        else if (level == "information")
97                setLevel(Message::PRIO_INFORMATION);
98        else if (level == "debug")
99                setLevel(Message::PRIO_DEBUG);
100        else if (level == "trace")
101                setLevel(Message::PRIO_TRACE);
102        else
103                throw InvalidArgumentException("Not a valid log level", level);
104}
105
106
107void Logger::setProperty(const std::string& name, const std::string& value)
108{
109        if (name == "channel")
110                setChannel(LoggingRegistry::defaultRegistry().channelForName(value));
111        else if (name == "level")
112                setLevel(value);
113        else 
114                Channel::setProperty(name, value);
115}
116
117
118void Logger::log(const Message& msg)
119{
120        if (_level >= msg.getPriority() && _pChannel)
121        {
122                _pChannel->log(msg);
123        }
124}
125
126
127void Logger::log(const Exception& exc)
128{
129        error(exc.displayText());
130}
131
132
133void Logger::dump(const std::string& msg, const void* buffer, std::size_t length, Message::Priority prio)
134{
135        if (_level >= prio && _pChannel)
136        {
137                std::string text(msg);
138                formatDump(text, buffer, length);
139                _pChannel->log(Message(_name, text, prio));
140        }
141}
142
143
144void Logger::setLevel(const std::string& name, int level)
145{
146        Mutex::ScopedLock lock(_mapMtx);
147
148        if (_pLoggerMap)
149        {
150                std::string::size_type len = name.length();
151                for (LoggerMap::iterator it = _pLoggerMap->begin(); it != _pLoggerMap->end(); ++it)
152                {
153                        if (len == 0 || 
154                                (it->first.compare(0, len, name) == 0 && (it->first.length() == len || it->first[len] == '.')))
155                        {
156                                it->second->setLevel(level);
157                        }
158                }
159        }
160}
161
162
163void Logger::setChannel(const std::string& name, Channel* pChannel)
164{
165        Mutex::ScopedLock lock(_mapMtx);
166
167        if (_pLoggerMap)
168        {
169                std::string::size_type len = name.length();
170                for (LoggerMap::iterator it = _pLoggerMap->begin(); it != _pLoggerMap->end(); ++it)
171                {
172                        if (len == 0 ||
173                                (it->first.compare(0, len, name) == 0 && (it->first.length() == len || it->first[len] == '.')))
174                        {
175                                it->second->setChannel(pChannel);
176                        }
177                }
178        }
179}
180
181
182void Logger::setProperty(const std::string& loggerName, const std::string& propertyName, const std::string& value)
183{
184        Mutex::ScopedLock lock(_mapMtx);
185
186        if (_pLoggerMap)
187        {
188                std::string::size_type len = loggerName.length();
189                for (LoggerMap::iterator it = _pLoggerMap->begin(); it != _pLoggerMap->end(); ++it)
190                {
191                        if (len == 0 ||
192                                (it->first.compare(0, len, loggerName) == 0 && (it->first.length() == len || it->first[len] == '.')))
193                        {
194                                it->second->setProperty(propertyName, value);
195                        }
196                }
197        }
198}
199
200
201std::string Logger::format(const std::string& fmt, const std::string& arg)
202{
203        std::string args[] =
204        {
205                arg
206        };
207        return format(fmt, 1, args);
208}
209
210
211std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1)
212{
213        std::string args[] =
214        {
215                arg0,
216                arg1
217        };
218        return format(fmt, 2, args);
219}
220
221
222std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2)
223{
224        std::string args[] =
225        {
226                arg0,
227                arg1,
228                arg2
229        };
230        return format(fmt, 3, args);
231}
232
233
234std::string Logger::format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3)
235{
236        std::string args[] =
237        {
238                arg0,
239                arg1,
240                arg2,
241                arg3
242        };
243        return format(fmt, 4, args);
244}
245
246
247std::string Logger::format(const std::string& fmt, int argc, std::string argv[])
248{
249        std::string result;
250        std::string::const_iterator it = fmt.begin();
251        while (it != fmt.end())
252        {
253                if (*it == '$')
254                {
255                        ++it;
256                        if (*it == '$')
257                        {
258                                result += '$';
259                        }
260                        else if (*it >= '0' && *it <= '9')
261                        {
262                                int i = *it - '0';
263                                if (i < argc)
264                                        result += argv[i];
265                        }
266                        else
267                        {
268                                result += '$';
269                                result += *it;
270                        }
271                }
272                else result += *it;
273                ++it;
274        }
275        return result;
276}
277
278
279void Logger::formatDump(std::string& message, const void* buffer, std::size_t length)
280{
281        const int BYTES_PER_LINE = 16;
282
283        message.reserve(message.size() + length*6);
284        if (!message.empty()) message.append("\n");
285        unsigned char* base = (unsigned char*) buffer;
286        int addr = 0;
287        while (addr < length)
288        {
289                if (addr > 0) message.append("\n");
290                message.append(NumberFormatter::formatHex(addr, 4));
291                message.append("  ");
292                int offset = 0;
293                while (addr + offset < length && offset < BYTES_PER_LINE)
294                {
295                        message.append(NumberFormatter::formatHex(base[addr + offset], 2));
296                        message.append(offset == 7 ? "  " : " ");
297                        ++offset;
298                }
299                if (offset < 7) message.append(" ");
300                while (offset < BYTES_PER_LINE) { message.append("   "); ++offset; }
301                message.append(" ");
302                offset = 0;
303                while (addr + offset < length && offset < BYTES_PER_LINE)
304                {
305                        unsigned char c = base[addr + offset];
306                        message += (c >= 32 && c < 127) ? (char) c : '.';
307                        ++offset;
308                }
309                addr += BYTES_PER_LINE;
310        }
311}
312
313
314Logger& Logger::get(const std::string& name)
315{
316        Mutex::ScopedLock lock(_mapMtx);
317
318        return unsafeGet(name);
319}
320
321
322Logger& Logger::unsafeGet(const std::string& name)
323{
324        Logger* pLogger = find(name);
325        if (!pLogger)
326        {
327                if (name == ROOT)
328                {
329                        pLogger = new Logger(name, 0, Message::PRIO_INFORMATION);
330                }
331                else
332                {
333                        Logger& par = parent(name);
334                        pLogger = new Logger(name, par.getChannel(), par.getLevel());
335                }
336                add(pLogger);
337        }
338        return *pLogger;
339}
340
341
342Logger& Logger::create(const std::string& name, Channel* pChannel, int level)
343{
344        Mutex::ScopedLock lock(_mapMtx);
345
346        if (find(name)) throw ExistsException();
347        Logger* pLogger = new Logger(name, pChannel, level);
348        add(pLogger);
349        return *pLogger;
350}
351
352
353Logger& Logger::root()
354{
355        Mutex::ScopedLock lock(_mapMtx);
356
357        return unsafeGet(ROOT);
358}
359
360
361Logger* Logger::has(const std::string& name)
362{
363        Mutex::ScopedLock lock(_mapMtx);
364
365        return find(name);
366}
367
368
369void Logger::shutdown()
370{
371        Mutex::ScopedLock lock(_mapMtx);
372
373        if (_pLoggerMap)
374        {
375                for (LoggerMap::iterator it = _pLoggerMap->begin(); it != _pLoggerMap->end(); ++it)
376                {
377                        it->second->release();
378                }
379                delete _pLoggerMap;
380                _pLoggerMap = 0;
381        }
382}
383
384
385Logger* Logger::find(const std::string& name)
386{
387        if (_pLoggerMap)
388        {
389                LoggerMap::iterator it = _pLoggerMap->find(name);
390                if (it != _pLoggerMap->end())
391                        return it->second;
392        }
393        return 0;
394}
395
396
397void Logger::destroy(const std::string& name)
398{
399        Mutex::ScopedLock lock(_mapMtx);
400
401        if (_pLoggerMap)
402        {
403                LoggerMap::iterator it = _pLoggerMap->find(name);
404                if (it != _pLoggerMap->end())
405                {
406                        it->second->release();
407                        _pLoggerMap->erase(it);
408                }
409        }
410}
411
412
413void Logger::names(std::vector<std::string>& names)
414{
415        Mutex::ScopedLock lock(_mapMtx);
416
417        names.clear();
418        if (_pLoggerMap)
419        {
420                for (LoggerMap::const_iterator it = _pLoggerMap->begin(); it != _pLoggerMap->end(); ++it)
421                {
422                        names.push_back(it->first);
423                }
424        }
425}
426
427
428Logger& Logger::parent(const std::string& name)
429{
430        std::string::size_type pos = name.rfind('.');
431        if (pos != std::string::npos)
432        {
433                std::string pname = name.substr(0, pos);
434                Logger* pParent = find(pname);
435                if (pParent)
436                        return *pParent;
437                else
438                        return parent(pname);
439        }
440        else return unsafeGet(ROOT);
441}
442
443
444class AutoLoggerShutdown
445{
446public:
447        AutoLoggerShutdown()
448        {
449        }
450        ~AutoLoggerShutdown()
451        {
452                Logger::shutdown();
453        }
454};
455
456
457void Logger::add(Logger* pLogger)
458{
459        static AutoLoggerShutdown als;
460
461        if (!_pLoggerMap)
462                _pLoggerMap = new LoggerMap;
463        _pLoggerMap->insert(LoggerMap::value_type(pLogger->name(), pLogger));
464}
465
466
467} // namespace Poco
Note: See TracBrowser for help on using the repository browser.