MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FileLogHandler.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <ndb_global.h>
20 #include <FileLogHandler.hpp>
21 #include <util/File.hpp>
22 
23 //
24 // PUBLIC
25 //
26 FileLogHandler::FileLogHandler(const char* aFileName,
27  int maxNoFiles,
28  long maxFileSize,
29  unsigned int maxLogEntries) :
30  LogHandler(),
31  m_maxNoFiles(maxNoFiles),
32  m_maxFileSize(maxFileSize),
33  m_maxLogEntries(maxLogEntries)
34 {
35  m_pLogFile = new File_class(aFileName, "a+");
36 }
37 
39 {
40  delete m_pLogFile;
41 }
42 
43 bool
45 {
46  bool rc = true;
47 
48  if (m_pLogFile->open())
49  {
50  if (isTimeForNewFile())
51  {
52  if (!createNewFile())
53  {
54  setErrorCode(errno);
55  rc = false;
56  }
57  }
58  }
59  else
60  {
61  setErrorCode(errno);
62  rc = false;
63  }
64 
65  return rc;
66 }
67 
68 bool
70 {
71  return m_pLogFile->is_open();
72 }
73 
74 bool
76 {
77  bool rc = true;
78  if (!m_pLogFile->close())
79  {
80  setErrorCode(errno);
81  rc = false;
82  }
83 
84  return rc;
85 }
86 
87 void
89 {
90  char str[LogHandler::MAX_HEADER_LENGTH];
91  m_pLogFile->writeChar(getDefaultHeader(str, pCategory, level));
92 }
93 
94 void
96 {
97  m_pLogFile->writeChar(pMsg);
98 }
99 
100 void
102 {
103  static int callCount = 0;
104  m_pLogFile->writeChar(getDefaultFooter());
111  if (callCount % m_maxLogEntries != 0) // Check every m_maxLogEntries
112  {
113  if (isTimeForNewFile())
114  {
115  if (!createNewFile())
116  {
117  // Baby one more time...
118  createNewFile();
119  }
120  }
121  callCount = 0;
122  }
123  callCount++;
124 
125  m_pLogFile->flush();
126 }
127 
128 
129 //
130 // PRIVATE
131 //
132 
133 bool
134 FileLogHandler::isTimeForNewFile()
135 {
136  return (m_pLogFile->size() >= m_maxFileSize);
137 }
138 
139 off_t FileLogHandler::getCurrentSize()
140 {
141  return m_pLogFile->size();
142 }
143 
144 bool
145 FileLogHandler::createNewFile()
146 {
147  bool rc = true;
148  int fileNo = 1;
149  char newName[PATH_MAX];
150  time_t newMtime, preMtime = 0;
151 
152  do
153  {
154  if (fileNo >= m_maxNoFiles)
155  {
156  fileNo = 1;
157  BaseString::snprintf(newName, sizeof(newName),
158  "%s.%d", m_pLogFile->getName(), fileNo);
159  break;
160  }
161  BaseString::snprintf(newName, sizeof(newName),
162  "%s.%d", m_pLogFile->getName(), fileNo++);
163  newMtime = File_class::mtime(newName);
164  if (newMtime < preMtime)
165  {
166  break;
167  }
168  else
169  {
170  preMtime = newMtime;
171  }
172  } while (File_class::exists(newName));
173 
174  m_pLogFile->close();
175  if (!File_class::rename(m_pLogFile->getName(), newName))
176  {
177  setErrorCode(errno);
178  rc = false;
179  }
180 
181  // Open again
182  if (!m_pLogFile->open())
183  {
184  setErrorCode(errno);
185  rc = false;
186  }
187 
188  return rc;
189 }
190 
191 bool
192 FileLogHandler::setParam(const BaseString &param, const BaseString &value){
193  if(param == "filename")
194  return setFilename(value);
195  if(param == "maxsize")
196  return setMaxSize(value);
197  if(param == "maxfiles")
198  return setMaxFiles(value);
199  setErrorStr("Invalid parameter");
200  return false;
201 }
202 
204 {
205  config.assfmt("FILE:filename=%s,maxsize=%lu,maxfiles=%u",
206  m_pLogFile->getName(),
207  m_maxFileSize,
208  m_maxNoFiles);
209  return true;
210 }
211 
212 bool
213 FileLogHandler::setFilename(const BaseString &filename) {
214  close();
215  if(m_pLogFile)
216  delete m_pLogFile;
217  m_pLogFile = new File_class(filename.c_str(), "a+");
218  return open();
219 }
220 
221 bool
222 FileLogHandler::setMaxSize(const BaseString &size) {
223  char *end;
224  long val = strtol(size.c_str(), &end, 0); /* XXX */
225  if(size.c_str() == end || val < 0)
226  {
227  setErrorStr("Invalid file size");
228  return false;
229  }
230  if(end[0] == 'M')
231  val *= 1024*1024;
232  if(end[0] == 'k')
233  val *= 1024;
234 
235  m_maxFileSize = val;
236 
237  return true;
238 }
239 
240 bool
241 FileLogHandler::setMaxFiles(const BaseString &files) {
242  char *end;
243  long val = strtol(files.c_str(), &end, 0);
244  if(files.c_str() == end || val < 1)
245  {
246  setErrorStr("Invalid maximum number of files");
247  return false;
248  }
249  m_maxNoFiles = val;
250 
251  return true;
252 }
253 
254 bool
256  if(m_pLogFile == NULL)
257  {
258  setErrorStr("Log file cannot be null.");
259  return false;
260  }
261  return true;
262 }