source: XMLIO_V2/external/src/POCO/Foundation/FileChannel.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.3 KB
Line 
1//
2// FileChannel.cpp
3//
4// $Id: //poco/1.3/Foundation/src/FileChannel.cpp#3 $
5//
6// Library: Foundation
7// Package: Logging
8// Module:  FileChannel
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/FileChannel.h>
38#include <Poco/ArchiveStrategy.h>
39#include <Poco/RotateStrategy.h>
40#include <Poco/PurgeStrategy.h>
41#include <Poco/Message.h>
42#include <Poco/NumberParser.h>
43#include <Poco/DateTimeFormatter.h>
44#include <Poco/DateTime.h>
45#include <Poco/LocalDateTime.h>
46#include <Poco/String.h>
47#include <Poco/Timespan.h>
48#include <Poco/Exception.h>
49#include <cctype>
50
51
52namespace Poco {
53
54
55const std::string FileChannel::PROP_PATH       = "path";
56const std::string FileChannel::PROP_ROTATION   = "rotation";
57const std::string FileChannel::PROP_ARCHIVE    = "archive";
58const std::string FileChannel::PROP_TIMES      = "times";
59const std::string FileChannel::PROP_COMPRESS   = "compress";
60const std::string FileChannel::PROP_PURGEAGE   = "purgeAge";
61const std::string FileChannel::PROP_PURGECOUNT = "purgeCount";
62
63
64FileChannel::FileChannel(): 
65        _times("utc"),
66        _compress(false),
67        _pFile(0),
68        _pRotateStrategy(0),
69        _pArchiveStrategy(new ArchiveByNumberStrategy),
70        _pPurgeStrategy(0)
71{
72}
73
74
75FileChannel::FileChannel(const std::string& path):
76        _path(path),
77        _times("utc"),
78        _compress(false),
79        _pFile(0),
80        _pRotateStrategy(0),
81        _pArchiveStrategy(new ArchiveByNumberStrategy),
82        _pPurgeStrategy(0)
83{
84}
85
86
87FileChannel::~FileChannel()
88{
89        close();
90        delete _pRotateStrategy;
91        delete _pArchiveStrategy;
92        delete _pPurgeStrategy;
93}
94
95
96void FileChannel::open()
97{
98        FastMutex::ScopedLock lock(_mutex);
99       
100        if (!_pFile)
101        {
102                _pFile = new LogFile(_path);
103        }
104}
105
106
107void FileChannel::close()
108{
109        FastMutex::ScopedLock lock(_mutex);
110
111        delete _pFile;
112        _pFile = 0;
113}
114
115
116void FileChannel::log(const Message& msg)
117{
118        open();
119
120        FastMutex::ScopedLock lock(_mutex);
121
122        if (_pRotateStrategy && _pArchiveStrategy && _pRotateStrategy->mustRotate(_pFile))
123        {
124                try
125                {
126                        _pFile = _pArchiveStrategy->archive(_pFile);
127                        purge();
128                }
129                catch (...)
130                {
131                        _pFile = new LogFile(_path);
132                }
133                // we must call mustRotate() again to give the
134                // RotateByIntervalStrategy a chance to write its timestamp
135                // to the new file.
136                _pRotateStrategy->mustRotate(_pFile);
137        }
138        _pFile->write(msg.getText());
139}
140
141       
142void FileChannel::setProperty(const std::string& name, const std::string& value)
143{
144        FastMutex::ScopedLock lock(_mutex);
145
146        if (name == PROP_TIMES)
147        {
148                _times = value;
149
150                if (!_rotation.empty())
151                        setRotation(_rotation);
152
153                if (!_archive.empty())
154                        setArchive(_archive);
155        }
156        else if (name == PROP_PATH)
157                _path = value;
158        else if (name == PROP_ROTATION)
159                setRotation(value);
160        else if (name == PROP_ARCHIVE)
161                setArchive(value);
162        else if (name == PROP_COMPRESS)
163                setCompress(value);
164        else if (name == PROP_PURGEAGE)
165                setPurgeAge(value);
166        else if (name == PROP_PURGECOUNT)
167                setPurgeCount(value);
168        else
169                Channel::setProperty(name, value);
170}
171
172
173std::string FileChannel::getProperty(const std::string& name) const
174{
175        if (name == PROP_TIMES)
176                return _times;
177        else if (name == PROP_PATH)
178                return _path;
179        else if (name == PROP_ROTATION)
180                return _rotation;
181        else if (name == PROP_ARCHIVE)
182                return _archive;
183        else if (name == PROP_COMPRESS)
184                return std::string(_compress ? "true" : "false");
185        else if (name == PROP_PURGEAGE)
186                return _purgeAge;
187        else if (name == PROP_PURGECOUNT)
188                return _purgeCount;
189        else
190                return Channel::getProperty(name);
191}
192
193
194Timestamp FileChannel::creationDate() const
195{
196        if (_pFile)
197                return _pFile->creationDate();
198        else
199                return 0;
200}
201
202       
203UInt64 FileChannel::size() const
204{
205        if (_pFile)
206                return _pFile->size();
207        else
208                return 0;
209}
210
211
212const std::string& FileChannel::path() const
213{
214        return _path;
215}
216
217
218void FileChannel::setRotation(const std::string& rotation)
219{
220        std::string::const_iterator it  = rotation.begin();
221        std::string::const_iterator end = rotation.end();
222        int n = 0;
223        while (it != end && std::isspace(*it)) ++it;
224        while (it != end && std::isdigit(*it)) { n *= 10; n += *it++ - '0'; }
225        while (it != end && std::isspace(*it)) ++it;
226        std::string unit;
227        while (it != end && std::isalpha(*it)) unit += *it++;
228       
229        RotateStrategy* pStrategy = 0;
230        if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
231        {
232                if (_times == "utc")
233                        pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
234                else if (_times == "local")
235                        pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
236                else
237                        throw PropertyNotSupportedException("times", _times);
238        }
239        else if (unit == "daily")
240                pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
241        else if (unit == "weekly")
242                pStrategy = new RotateByIntervalStrategy(Timespan(7*Timespan::DAYS));
243        else if (unit == "monthly")
244                pStrategy = new RotateByIntervalStrategy(Timespan(30*Timespan::DAYS));
245        else if (unit == "seconds") // for testing only
246                pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::SECONDS));
247        else if (unit == "minutes")
248                pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::MINUTES));
249        else if (unit == "hours")
250                pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::HOURS));
251        else if (unit == "days")
252                pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::DAYS));
253        else if (unit == "weeks")
254                pStrategy = new RotateByIntervalStrategy(Timespan(n*7*Timespan::DAYS));
255        else if (unit == "months")
256                pStrategy = new RotateByIntervalStrategy(Timespan(n*30*Timespan::DAYS));
257        else if (unit == "K")
258                pStrategy = new RotateBySizeStrategy(n*1024);
259        else if (unit == "M")
260                pStrategy = new RotateBySizeStrategy(n*1024*1024);
261        else if (unit.empty())
262                pStrategy = new RotateBySizeStrategy(n);
263        else if (unit != "never")
264                throw InvalidArgumentException("rotation", rotation);
265        delete _pRotateStrategy;
266        _pRotateStrategy = pStrategy;
267        _rotation = rotation;
268}
269
270
271void FileChannel::setArchive(const std::string& archive)
272{
273        ArchiveStrategy* pStrategy = 0;
274        if (archive == "number")
275        {
276                pStrategy = new ArchiveByNumberStrategy;
277        }
278        else if (archive == "timestamp")
279        {
280                if (_times == "utc")
281                        pStrategy = new ArchiveByTimestampStrategy<DateTime>;
282                else if (_times == "local")
283                        pStrategy = new ArchiveByTimestampStrategy<LocalDateTime>;
284                else
285                        throw PropertyNotSupportedException("times", _times);
286        }
287        else throw InvalidArgumentException("archive", archive);
288        delete _pArchiveStrategy;
289        pStrategy->compress(_compress);
290        _pArchiveStrategy = pStrategy;
291        _archive = archive;
292}
293
294
295void FileChannel::setCompress(const std::string& compress)
296{
297        _compress = icompare(compress, "true") == 0;
298        if (_pArchiveStrategy)
299                _pArchiveStrategy->compress(_compress);
300}
301
302
303void FileChannel::setPurgeAge(const std::string& age)
304{
305        std::string::const_iterator it  = age.begin();
306        std::string::const_iterator end = age.end();
307        int n = 0;
308        while (it != end && std::isspace(*it)) ++it;
309        while (it != end && std::isdigit(*it)) { n *= 10; n += *it++ - '0'; }
310        while (it != end && std::isspace(*it)) ++it;
311        std::string unit;
312        while (it != end && std::isalpha(*it)) unit += *it++;
313       
314        Timespan::TimeDiff factor = Timespan::SECONDS;
315        if (unit == "minutes")
316                factor = Timespan::MINUTES;
317        else if (unit == "hours")
318                factor = Timespan::HOURS;
319        else if (unit == "days")
320                factor = Timespan::DAYS;
321        else if (unit == "weeks")
322                factor = 7*Timespan::DAYS;
323        else if (unit == "months")
324                factor = 30*Timespan::DAYS;
325        else if (unit != "seconds")
326                throw InvalidArgumentException("purgeAge", age);
327               
328        delete _pPurgeStrategy;
329        _pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
330        _purgeAge = age;
331}
332
333
334void FileChannel::setPurgeCount(const std::string& count)
335{
336        std::string::const_iterator it  = count.begin();
337        std::string::const_iterator end = count.end();
338        int n = 0;
339        while (it != end && std::isspace(*it)) ++it;
340        while (it != end && std::isdigit(*it)) { n *= 10; n += *it++ - '0'; }
341        while (it != end && std::isspace(*it)) ++it;
342
343        delete _pPurgeStrategy;
344        _pPurgeStrategy = new PurgeByCountStrategy(n);
345        _purgeCount = count;
346}
347
348
349void FileChannel::purge()
350{
351        if (_pPurgeStrategy)
352        {
353                try
354                {
355                        _pPurgeStrategy->purge(_path);
356                }
357                catch (...)
358                {
359                }
360        }
361}
362
363
364} // namespace Poco
Note: See TracBrowser for help on using the repository browser.