libassa  3.5.1
FileLogger.cpp
Go to the documentation of this file.
1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // FileLogger.cpp
4 //------------------------------------------------------------------------------
5 // $Id: FileLogger.cpp,v 1.10 2006/07/20 02:30:53 vlg Exp $
6 //------------------------------------------------------------------------------
7 // Copyright (C) 1997-2002,2005 Vladislav Grinchenko
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Library General Public
11 // License as published by the Free Software Foundation; either
12 // version 2 of the License, or (at your option) any later version.
13 //------------------------------------------------------------------------------
14 
15 #include <stdio.h>
16 #include <stdarg.h> // vsprintf(3)
17 
18 #include <sys/types.h> // stat(2)
19 #include <sys/stat.h> // stat(2)
20 #include <unistd.h> // stat(2)
21 
22 #include <string>
23 #include <iomanip>
24 
25 #include <assa/TimeVal.h>
26 #include <assa/FileLogger.h>
27 #include <assa/Assure.h>
28 
29 using namespace ASSA;
30 
31 int
33 log_open (const char* logfname_, u_long groups_, u_long maxsize_)
34 {
35 // std::cout << "Enter: FileLogger::log_open(fname=\""
36 // << logfname_ << "\""
37 // << " groups=0x" << std::setw(8) << std::hex << groups_
38 // << " maxsize=" << std::dec << maxsize_ << ")\n";
39 
40  if (logfname_ == NULL || maxsize_ <= 0) {
41 // std::cout << "FileLogger::log_open() failed 1\n";
42  errno = EINVAL;
43  return -1;
44  }
45 
46  if (m_state == opened) {
47 // std::cout << "FileLogger::log_open() already open\n";
48  errno = EEXIST;
49  return -1;
50  }
51 
52  m_logfname = logfname_;
53  m_groups = groups_;
54  m_maxsize = maxsize_;
55 
56  m_sink.open (m_logfname.c_str (), std::ios::out | std::ios::app);
57 
58  if (!m_sink) {
59 // std::cout << "FileLogger::log_open() failed to open()!\n";
60  return -1;
61  }
62 // std::cout << "Success on FileLogger::log_open()\n";
63 
64  m_state = opened;
65  return 0;
66 }
67 
68 int
70 log_close (void)
71 {
72  if (m_state != closed) {
73  m_sink << std::flush;
74  m_sink.close ();
75  m_state = closed;
76 
77  if (m_groups == 0) {
78  ::unlink (m_logfname.c_str ());
79  }
80  m_logfname.empty ();
81  m_maxsize = 0;
82  m_bytecount = 0;
83  }
84  return 0;
85 }
86 
115 int
117 log_msg (Group g_,
118  size_t indent_level_,
119  const string& func_name_,
120  size_t expected_sz_,
121  const char* fmt_,
122  va_list msg_list_)
123 {
124 // std::cout << "FileLogger::log_msg() enter\n"
125 // << "group__=0x" << std::setw(8) << std::hex << (u_long)g_ << "\n";
126 
127  if (m_state == closed) {
128 // std::cout << "FileLogger::log_msg() sink closed!\n";
129  errno = EPERM;
130  return -1;
131  }
132 
133  if (! group_enabled (g_)) {
134 // std::cout << "FileLogger::log_msg() group is not enabled!\n"
135 // << "m_groups=0x"
136 // << std::setw(8) << std::hex << m_groups << "\n";
137  return 0;
138  }
139 
141  m_bytecount += indent_func_name (m_sink, func_name_,indent_level_,FUNC_MSG);
142 
143  bool release = false;
144  char* msgbuf_ptr = format_msg (expected_sz_, fmt_, msg_list_, release);
145  if (msgbuf_ptr == NULL) {
146 // std::cout << "FileLogger::log_msg() call to format_msg() failed!"
147 // << " fmt_= \"" << fmt_ << "\"\n" << std::flush;
148  return -1; // failed to format
149  }
150  m_sink << msgbuf_ptr << std::flush;
151  m_bytecount += strlen (msgbuf_ptr);
152 
153  if (release) {
154  delete [] msgbuf_ptr;
155  }
156 
157  return handle_rollover ();
158 }
159 
160 int
162 log_func (Group g_, size_t indent_level_, const string& func_name_,
163  marker_t type_)
164 {
165  if (m_state == closed) {
166  errno = EPERM;
167  return -1;
168  }
169 
170  if (! group_enabled (g_)) {
171  return 0;
172  }
173 
175  m_bytecount += indent_func_name (m_sink, func_name_, indent_level_, type_);
176  m_sink << ((type_ == FUNC_ENTRY) ? "---v---\n" : "---^---\n") << std::flush;
177  m_bytecount += ::strlen ("---v---\n");
178 
179  return handle_rollover ();
180 }
181 
182 int
184 log_raw_msg (const string& msg_)
185 {
186  if (m_state == closed) {
187  errno = EPERM;
188  return -1;
189  }
190 
191  m_sink << msg_ << std::flush;
192  m_bytecount += msg_.length ();
193 
194  return handle_rollover ();
195 }
196 
197 int
200 {
201  if (m_bytecount >= m_maxsize) {
202  struct stat fst;
203  if (::stat (m_logfname.c_str(), &fst) == 0) {
204  if (S_ISREG (fst.st_mode)) {
205  m_sink << "\nReached maximum allowable size\n"
206  << "m_bytecount = " << m_bytecount
207  << ", m_maxsize = " << m_maxsize << std::endl;
208  m_sink.close ();
209  m_state = closed;
210  m_bytecount = 0;
211 
212  string newname = m_logfname + ".0";
213  unlink (newname.c_str ());
214  rename (m_logfname.c_str (), newname.c_str ());
215  m_sink.open (m_logfname.c_str (),
216  std::ios::app | std::ios::out);
217  if (!m_sink) {
218  return -1;
219  }
220  m_state = opened;
221  }
222  else if (S_ISCHR (fst.st_mode)) { // It is /dev/null
223  m_bytecount = 0;
224  }
225  else {
226  Assure_exit (1);
227  }
228  }
229  }
230  return 0;
231 }
232 
233 void
235 dump (void)
236 {
237 #ifdef BUG_HUNTING
238  if (m_state == opened) {
239  m_sink << "m_logfname = \"" << m_logfname << "\"\n"
240  << "m_groups = 0x";
241  char oldfill = m_sink.fill ('0');
242  m_sink << std::setw(8) << std::hex << m_groups << '\n' << std::dec;
243  m_sink.fill (oldfill);
244  m_sink << "m_indent_step = " << m_indent_step << '\n'
245  << "m_tmflg = " << m_tmflg << '\n'
246  << "m_maxsize = " << m_maxsize << '\n'
247  << "m_state = opened\n"
248  << "m_bytecount = " << m_bytecount << std::endl;
249  }
250 #endif
251 }
A collection of assert function wrappers.
#define Assure_exit(exp_)
Macro that makes program exit if assert fails.
Definition: Assure.h:39
Implemention of a Logger as a disk-based file.
unsigned long u_long
Definition: Logger_Impl.h:41
Class TimeVal is a wrapper around UNIX timeval structure.
void dump(void)
Definition: FileLogger.cpp:235
virtual int log_func(Group g_, size_t indent_level_, const string &func_name_, marker_t type_)
Definition: FileLogger.cpp:162
virtual int log_open(const char *logfname_, u_long groups_, u_long maxsize_=10485760)
Open File Logger.
Definition: FileLogger.cpp:33
virtual int log_close(void)
Definition: FileLogger.cpp:70
virtual int log_msg(Group g_, size_t indent_level_, const string &func_name_, size_t expected_sz_, const char *fmt_, va_list)
If output string is longer then LOGGER_MAXLINE-1, it is truncated to that size.
Definition: FileLogger.cpp:117
u_long m_maxsize
Definition: FileLogger.h:69
std::ofstream m_sink
Definition: FileLogger.h:68
state_t m_state
Definition: FileLogger.h:70
int log_raw_msg(const string &msg_)
Log message as it is (raw) without indentation or timestamping, but still perform byte counting and t...
Definition: FileLogger.cpp:184
u_long m_bytecount
Definition: FileLogger.h:71
char * format_msg(size_t expected_sz_, const char *fmt_, va_list vap_, bool &release_)
Format and put the message in the buffer.
Definition: Logger_Impl.cpp:86
virtual u_short indent_func_name(ostream &sink_, const string &funcname_, size_t indent_level_, marker_t type_)
Definition: Logger_Impl.cpp:54
bool group_enabled(Group g_) const
Definition: Logger_Impl.h:164
u_short m_indent_step
Indentation step.
Definition: Logger_Impl.h:236
u_long m_groups
Enabled groups.
Definition: Logger_Impl.h:239
string m_logfname
Log file name.
Definition: Logger_Impl.h:242
virtual u_short add_timestamp(ostream &sink_)
Definition: Logger_Impl.cpp:35
bool m_tmflg
Timestamp on/off flag.
Definition: Logger_Impl.h:245
Definition: Acceptor.h:40
Socket & flush(Socket &os_)
flush manipulator.
Definition: Socket.h:587
marker_t
Definition: LogMask.h:67
@ FUNC_ENTRY
Definition: LogMask.h:69
@ FUNC_MSG
Definition: LogMask.h:68
Group
Definition: LogMask.h:25
Socket & endl(Socket &os_)
endl manipulator.
Definition: Socket.h:602