1 /*
2 Copyright (C) 2003-2006, 2008 MySQL AB
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, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License, version 2.0, for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include "LogHandler.hpp"
27
28 #include <NdbTick.h>
29
30 //
31 // PUBLIC
32 //
LogHandler()33 LogHandler::LogHandler() :
34 m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
35 m_errorCode(0),
36 m_errorStr(NULL)
37 {
38 m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
39 m_count_repeated_messages= 0;
40 m_last_category[0]= 0;
41 m_last_message[0]= 0;
42 m_last_log_time= 0;
43 m_now= 0;
44 m_last_level= (Logger::LoggerLevel)-1;
45 }
46
~LogHandler()47 LogHandler::~LogHandler()
48 {
49 }
50
51 void
append(const char * pCategory,Logger::LoggerLevel level,const char * pMsg)52 LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
53 const char* pMsg)
54 {
55 time_t now;
56 now= ::time((time_t*)NULL);
57
58 if (m_max_repeat_frequency == 0 ||
59 level != m_last_level ||
60 strcmp(pCategory, m_last_category) ||
61 strcmp(pMsg, m_last_message))
62 {
63 if (m_count_repeated_messages > 0) // print that message
64 append_impl(m_last_category, m_last_level, m_last_message);
65
66 m_last_level= level;
67 strncpy(m_last_category, pCategory, sizeof(m_last_category));
68 strncpy(m_last_message, pMsg, sizeof(m_last_message));
69 }
70 else // repeated message
71 {
72 if (now < (time_t) (m_last_log_time+m_max_repeat_frequency))
73 {
74 m_count_repeated_messages++;
75 m_now= now;
76 return;
77 }
78 }
79
80 m_now= now;
81
82 append_impl(pCategory, level, pMsg);
83 m_last_log_time= now;
84 }
85
86 void
append_impl(const char * pCategory,Logger::LoggerLevel level,const char * pMsg)87 LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level,
88 const char* pMsg)
89 {
90 writeHeader(pCategory, level);
91 if (m_count_repeated_messages <= 1)
92 writeMessage(pMsg);
93 else
94 {
95 BaseString str(pMsg);
96 str.appfmt(" - Repeated %d times", m_count_repeated_messages);
97 writeMessage(str.c_str());
98 }
99 m_count_repeated_messages= 0;
100 writeFooter();
101 }
102
103 const char*
getDefaultHeader(char * pStr,const char * pCategory,Logger::LoggerLevel level) const104 LogHandler::getDefaultHeader(char* pStr, const char* pCategory,
105 Logger::LoggerLevel level) const
106 {
107 char time[MAX_DATE_TIME_HEADER_LENGTH];
108 BaseString::snprintf(pStr, MAX_HEADER_LENGTH, "%s [%s] %s -- ",
109 getTimeAsString((char*)time),
110 pCategory,
111 Logger::LoggerLevelNames[level]);
112
113 return pStr;
114 }
115
116
117 const char*
getDefaultFooter() const118 LogHandler::getDefaultFooter() const
119 {
120 return "\n";
121 }
122
123 const char*
getDateTimeFormat() const124 LogHandler::getDateTimeFormat() const
125 {
126 return m_pDateTimeFormat;
127 }
128
129 void
setDateTimeFormat(const char * pFormat)130 LogHandler::setDateTimeFormat(const char* pFormat)
131 {
132 m_pDateTimeFormat = (char*)pFormat;
133 }
134
135 char*
getTimeAsString(char * pStr) const136 LogHandler::getTimeAsString(char* pStr) const
137 {
138 struct tm* tm_now;
139 tm_now = ::localtime(&m_now); //uses the "current" timezone
140
141 BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,
142 m_pDateTimeFormat,
143 tm_now->tm_year + 1900,
144 tm_now->tm_mon + 1, //month is [0,11]. +1 -> [1,12]
145 tm_now->tm_mday,
146 tm_now->tm_hour,
147 tm_now->tm_min,
148 tm_now->tm_sec);
149
150 return pStr;
151 }
152
153 int
getErrorCode() const154 LogHandler::getErrorCode() const
155 {
156 return m_errorCode;
157 }
158
159 void
setErrorCode(int code)160 LogHandler::setErrorCode(int code)
161 {
162 m_errorCode = code;
163 }
164
165
166 char*
getErrorStr()167 LogHandler::getErrorStr()
168 {
169 return m_errorStr;
170 }
171
172 void
setErrorStr(const char * str)173 LogHandler::setErrorStr(const char* str)
174 {
175 m_errorStr= (char*) str;
176 }
177
178 bool
parseParams(const BaseString & _params)179 LogHandler::parseParams(const BaseString &_params) {
180 Vector<BaseString> v_args;
181
182 bool ret = true;
183
184 _params.split(v_args, ",");
185 for(size_t i=0; i < v_args.size(); i++) {
186 Vector<BaseString> v_param_value;
187 if(v_args[i].split(v_param_value, "=", 2) != 2)
188 {
189 ret = false;
190 setErrorStr("Can't find key=value pair.");
191 }
192 else
193 {
194 v_param_value[0].trim(" \t");
195 if (!setParam(v_param_value[0], v_param_value[1]))
196 {
197 ret = false;
198 }
199 }
200 }
201
202 if(!checkParams())
203 ret = false;
204 return ret;
205 }
206
207 bool
checkParams()208 LogHandler::checkParams() {
209 return true;
210 }
211
setRepeatFrequency(unsigned val)212 void LogHandler::setRepeatFrequency(unsigned val)
213 {
214 m_max_repeat_frequency= val;
215 }
216
217 //
218 // PRIVATE
219 //
220