~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/common/logger/FileLogHandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include <FileLogHandler.hpp>
 
18
#include <File.hpp>
 
19
 
 
20
//
 
21
// PUBLIC
 
22
//
 
23
 
 
24
FileLogHandler::FileLogHandler() : 
 
25
  LogHandler(),
 
26
  m_maxNoFiles(MAX_NO_FILES), 
 
27
  m_maxFileSize(MAX_FILE_SIZE),
 
28
  m_maxLogEntries(MAX_LOG_ENTRIES)
 
29
 
 
30
{
 
31
  m_pLogFile = new File_class("logger.log", "a+");
 
32
}
 
33
 
 
34
FileLogHandler::FileLogHandler(const char* aFileName, 
 
35
                               int maxNoFiles, 
 
36
                               long maxFileSize,
 
37
                               unsigned int maxLogEntries) : 
 
38
  LogHandler(),
 
39
  m_maxNoFiles(maxNoFiles), 
 
40
  m_maxFileSize(maxFileSize),
 
41
  m_maxLogEntries(maxLogEntries)
 
42
{
 
43
  m_pLogFile = new File_class(aFileName, "a+");
 
44
}
 
45
 
 
46
FileLogHandler::~FileLogHandler()
 
47
{
 
48
  delete m_pLogFile;
 
49
}
 
50
 
 
51
bool
 
52
FileLogHandler::open()
 
53
{
 
54
  bool rc = true;
 
55
 
 
56
  if (m_pLogFile->open())
 
57
  {
 
58
    if (isTimeForNewFile())
 
59
    {
 
60
      if (!createNewFile())
 
61
      {
 
62
        setErrorCode(errno);
 
63
        rc = false; 
 
64
      }
 
65
    }
 
66
  }
 
67
  else
 
68
  {
 
69
    setErrorCode(errno);
 
70
    rc = false;
 
71
  }
 
72
 
 
73
  return rc;
 
74
}
 
75
 
 
76
bool
 
77
FileLogHandler::close()
 
78
{
 
79
  bool rc = true;
 
80
  if (!m_pLogFile->close())
 
81
  {
 
82
    setErrorCode(errno);
 
83
    rc = false;
 
84
  }     
 
85
 
 
86
  return rc;
 
87
}
 
88
 
 
89
void 
 
90
FileLogHandler::writeHeader(const char* pCategory, Logger::LoggerLevel level)
 
91
{
 
92
  char str[LogHandler::MAX_HEADER_LENGTH];
 
93
  m_pLogFile->writeChar(getDefaultHeader(str, pCategory, level));
 
94
}
 
95
 
 
96
void 
 
97
FileLogHandler::writeMessage(const char* pMsg)
 
98
{
 
99
  m_pLogFile->writeChar(pMsg);
 
100
}
 
101
 
 
102
void 
 
103
FileLogHandler::writeFooter()
 
104
{
 
105
  static int callCount = 0;
 
106
  m_pLogFile->writeChar(getDefaultFooter());
 
107
  /**
 
108
   * The reason I also check the number of log entries instead of
 
109
   * only the log size, is that I do not want to check the file size
 
110
   * after each log entry which requires system calls and is quite slow.
 
111
   * TODO: Any better way?
 
112
   */
 
113
  if (callCount % m_maxLogEntries != 0) // Check every m_maxLogEntries
 
114
  {
 
115
    if (isTimeForNewFile())
 
116
    {
 
117
      if (!createNewFile())
 
118
      {
 
119
        // Baby one more time...
 
120
        createNewFile();
 
121
      }
 
122
    }   
 
123
    callCount = 0;
 
124
  }
 
125
  callCount++;
 
126
 
 
127
  m_pLogFile->flush();
 
128
}
 
129
 
 
130
 
 
131
//
 
132
// PRIVATE
 
133
//
 
134
 
 
135
bool 
 
136
FileLogHandler::isTimeForNewFile()
 
137
{
 
138
  return (m_pLogFile->size() >= m_maxFileSize); 
 
139
}
 
140
 
 
141
bool
 
142
FileLogHandler::createNewFile()
 
143
{
 
144
  bool rc = true;       
 
145
  int fileNo = 1;
 
146
  char newName[PATH_MAX];
 
147
  time_t newMtime, preMtime = 0;
 
148
 
 
149
  do
 
150
  {
 
151
    if (fileNo >= m_maxNoFiles)
 
152
    {
 
153
      fileNo = 1;
 
154
      BaseString::snprintf(newName, sizeof(newName),
 
155
                 "%s.%d", m_pLogFile->getName(), fileNo);
 
156
      break;
 
157
    }           
 
158
    BaseString::snprintf(newName, sizeof(newName),
 
159
               "%s.%d", m_pLogFile->getName(), fileNo++); 
 
160
    newMtime = File_class::mtime(newName);
 
161
    if (newMtime < preMtime) 
 
162
    {
 
163
      break;
 
164
    }
 
165
    else
 
166
    {
 
167
      preMtime = newMtime;
 
168
    }
 
169
  } while (File_class::exists(newName));
 
170
  
 
171
  m_pLogFile->close();  
 
172
  if (!File_class::rename(m_pLogFile->getName(), newName))
 
173
  {             
 
174
    setErrorCode(errno);
 
175
    rc = false;
 
176
  }
 
177
 
 
178
  // Open again
 
179
  if (!m_pLogFile->open())
 
180
  {
 
181
    setErrorCode(errno);
 
182
    rc = false;
 
183
  }                             
 
184
  
 
185
  return rc;
 
186
}
 
187
 
 
188
bool
 
189
FileLogHandler::setParam(const BaseString &param, const BaseString &value){
 
190
  if(param == "filename")
 
191
    return setFilename(value);
 
192
  if(param == "maxsize")
 
193
    return setMaxSize(value);
 
194
  if(param == "maxfiles")
 
195
    return setMaxFiles(value);
 
196
  setErrorStr("Invalid parameter");
 
197
  return false;
 
198
}
 
199
 
 
200
bool
 
201
FileLogHandler::setFilename(const BaseString &filename) {
 
202
  close();
 
203
  if(m_pLogFile)
 
204
    delete m_pLogFile;
 
205
  m_pLogFile = new File_class(filename.c_str(), "a+");
 
206
  return open();
 
207
}
 
208
 
 
209
bool
 
210
FileLogHandler::setMaxSize(const BaseString &size) {
 
211
  char *end;
 
212
  long val = strtol(size.c_str(), &end, 0); /* XXX */
 
213
  if(size.c_str() == end || val < 0)
 
214
  {
 
215
    setErrorStr("Invalid file size");
 
216
    return false;
 
217
  }
 
218
  if(end[0] == 'M')
 
219
    val *= 1024*1024;
 
220
  if(end[0] == 'k')
 
221
    val *= 1024;
 
222
 
 
223
  m_maxFileSize = val;
 
224
 
 
225
  return true;
 
226
}
 
227
 
 
228
bool
 
229
FileLogHandler::setMaxFiles(const BaseString &files) {
 
230
  char *end;
 
231
  long val = strtol(files.c_str(), &end, 0);
 
232
  if(files.c_str() == end || val < 1)
 
233
  {
 
234
    setErrorStr("Invalid maximum number of files");
 
235
    return false;
 
236
  }
 
237
  m_maxNoFiles = val;
 
238
 
 
239
  return true;
 
240
}
 
241
 
 
242
bool
 
243
FileLogHandler::checkParams() {
 
244
  if(m_pLogFile == NULL)
 
245
  {
 
246
    setErrorStr("Log file cannot be null.");
 
247
    return false;
 
248
  }
 
249
  return true;
 
250
}