]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/filelogger.cpp
Fix a bug in new logging API (global logstreams weren't notified of events if a speci...
[user/henk/code/inspircd.git] / src / filelogger.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 /* $Core: libIRCDfilelogger */
15
16 #include "inspircd.h"
17 #include <fstream>
18 #include "socketengine.h"
19 #include "inspircd_se_config.h"
20 #include "filelogger.h"
21
22 FileLogger::FileLogger(InspIRCd* Instance, FILE* logfile)
23 : ServerInstance(Instance), log(logfile), writeops(0)
24 {
25         if (log)
26         {
27                 Instance->SE->NonBlocking(fileno(log));
28                 SetFd(fileno(log));
29                 buffer.clear();
30         }
31 }
32
33 bool FileLogger::Readable()
34 {
35         return false;
36 }
37     
38 void FileLogger::HandleEvent(EventType, int)
39 {
40         WriteLogLine("");
41         if (log)
42                 ServerInstance->SE->DelFd(this);
43 }
44
45 void FileLogger::WriteLogLine(const std::string &line)
46 {
47         if (line.length())
48                 buffer.append(line);
49
50         if (log)
51         {
52                 int written = fprintf(log,"%s",buffer.c_str());
53 #ifdef WINDOWS
54                 buffer.clear();
55 #else
56                 if ((written >= 0) && (written < (int)buffer.length()))
57                 {
58                         buffer.erase(0, buffer.length());
59                         ServerInstance->SE->AddFd(this);
60                 }
61                 else if (written == -1)
62                 {
63                         if (errno == EAGAIN)
64                                 ServerInstance->SE->AddFd(this);
65                 }
66                 else
67                 {
68                         /* Wrote the whole buffer, and no need for write callback */
69                         buffer.clear();
70                 }
71 #endif
72                 if (writeops++ % 20)
73                 {
74                         fflush(log);
75                 }
76         }
77 }
78
79 void FileLogger::Close()
80 {
81         if (log)
82         {
83                 ServerInstance->SE->Blocking(fileno(log));
84
85                 if (buffer.size())
86                         fprintf(log,"%s",buffer.c_str());
87
88 #ifndef WINDOWS
89                 ServerInstance->SE->DelFd(this);
90 #endif
91
92                 fflush(log);
93                 fclose(log);
94         }
95
96         buffer.clear();
97 }
98
99 FileLogger::~FileLogger()
100 {
101         this->Close();
102 }
103
104
105 void FileLogStream::OnLog(int loglevel, const std::string &type, const std::string &text)
106 {
107         static char TIMESTR[26];
108         static time_t LAST = 0;
109
110         /* sanity check, just in case */
111         if (!ServerInstance->Config)
112                 return;
113
114         /* If we were given -debug we output all messages, regardless of configured loglevel */
115         if ((loglevel < ServerInstance->Config->LogLevel) && !ServerInstance->Config->forcedebug)
116                 return;
117
118         if (ServerInstance->Time() != LAST)
119         {
120                 time_t local = ServerInstance->Time();
121                 struct tm *timeinfo = localtime(&local);
122
123                 strlcpy(TIMESTR,asctime(timeinfo),26);
124                 TIMESTR[24] = ':';
125                 LAST = ServerInstance->Time();
126         }
127
128         if (ServerInstance->Config->log_file && ServerInstance->Config->writelog)
129         {
130                 std::string out = std::string(TIMESTR) + " " + text.c_str() + "\n";
131                 this->f->WriteLogLine(out);
132         }
133
134         if (ServerInstance->Config->nofork)
135         {
136                 printf("%s %s\n", TIMESTR, text.c_str());
137         }
138 }