1 /*
2  *  This file is part of nzbget. See <http://nzbget.net>.
3  *
4  *  Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
5  *  Copyright (C) 2007-2016 Andrey Prygunkov <hugbug@users.sourceforge.net>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #ifndef LOG_H
23 #define LOG_H
24 
25 #include "NString.h"
26 #include "Thread.h"
27 
28 void error(const char* msg, ...) PRINTF_SYNTAX(1);
29 void warn(const char* msg, ...) PRINTF_SYNTAX(1);
30 void info(const char* msg, ...) PRINTF_SYNTAX(1);
31 void detail(const char* msg, ...) PRINTF_SYNTAX(1);
32 
33 #ifdef DEBUG
34 #ifdef HAVE_VARIADIC_MACROS
35 void debug(const char* filename, const char* funcname, int lineNr, const char* msg, ...) PRINTF_SYNTAX(4);
36 #else
37 void debug(const char* msg, ...) PRINTF_SYNTAX(1);
38 #endif
39 #endif
40 
41 class Message
42 {
43 public:
44 	enum EKind
45 	{
46 		mkInfo,
47 		mkWarning,
48 		mkError,
49 		mkDebug,
50 		mkDetail
51 	};
52 
Message(uint32 id,EKind kind,time_t time,const char * text)53 	Message(uint32 id, EKind kind, time_t time, const char* text) :
54 		m_id(id), m_kind(kind), m_time(time), m_text(text) {}
GetId()55 	uint32 GetId() { return m_id; }
GetKind()56 	EKind GetKind() { return m_kind; }
GetTime()57 	time_t GetTime() { return m_time; }
GetText()58 	const char* GetText() { return m_text; }
59 
60 private:
61 	uint32 m_id;
62 	EKind m_kind;
63 	time_t m_time;
64 	CString m_text;
65 
66 	friend class Log;
67 };
68 
69 typedef std::deque<Message> MessageList;
70 typedef GuardedPtr<MessageList> GuardedMessageList;
71 
72 class Debuggable;
73 class DiskFile;
74 
75 class Log
76 {
77 public:
78 	Log();
79 	~Log();
GuardMessages()80 	GuardedMessageList GuardMessages() { return GuardedMessageList(&m_messages, &m_logMutex); }
81 	void Clear();
82 	void ResetLog();
83 	void InitOptions();
84 	void RegisterDebuggable(Debuggable* debuggable);
85 	void UnregisterDebuggable(Debuggable* debuggable);
86 	void LogDebugInfo();
87 	void IntervalCheck();
88 
89 private:
90 	typedef std::list<Debuggable*> Debuggables;
91 
92 	Mutex m_logMutex;
93 	MessageList m_messages;
94 	Debuggables m_debuggables;
95 	Mutex m_debugMutex;
96 	CString m_logFilename;
97 	std::unique_ptr<DiskFile> m_logFile;
98 	uint32 m_idGen = 0;
99 	time_t m_lastWritten = 0;
100 	bool m_optInit = false;
101 #ifdef DEBUG
102 	bool m_extraDebug;
103 #endif
104 
105 	void Filelog(const char* msg, ...) PRINTF_SYNTAX(2);
106 	void AddMessage(Message::EKind kind, const char* text);
107 	void RotateLog();
108 
109 	friend void error(const char* msg, ...);
110 	friend void warn(const char* msg, ...);
111 	friend void info(const char* msg, ...);
112 	friend void detail(const char* msg, ...);
113 #ifdef DEBUG
114 #ifdef HAVE_VARIADIC_MACROS
115 	friend void debug(const char* filename, const char* funcname, int lineNr, const char* msg, ...);
116 #else
117 	friend void debug(const char* msg, ...);
118 #endif
119 #endif
120 };
121 
122 #ifdef DEBUG
123 #ifdef HAVE_VARIADIC_MACROS
124 #define debug(...) debug(__FILE__, FUNCTION_MACRO_NAME, __LINE__, __VA_ARGS__)
125 #endif
126 #else
127 #define debug(...) do { } while(0)
128 #endif
129 
130 extern Log* g_Log;
131 
132 class Debuggable
133 {
134 public:
Debuggable()135 	Debuggable() { g_Log->RegisterDebuggable(this); }
~Debuggable()136 	virtual ~Debuggable() { g_Log->UnregisterDebuggable(this); }
137 protected:
138 	virtual void LogDebugInfo() = 0;
139 	friend class Log;
140 };
141 
142 #endif
143