source: nscp/modules/FileLogger/FileLogger.cpp @ 3bdaf18

0.4.00.4.10.4.2
Last change on this file since 3bdaf18 was 3bdaf18, checked in by Michael Medin <michael@…>, 3 years ago

Tweaks to building on linux, stil need to fix the utf8 issue and some modules...

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21
22#include <config.h>
23
24#include <string>
25#include <iostream>
26#include <fstream>
27
28#include <boost/date_time.hpp>
29
30#include "FileLogger.h"
31
32#include <utils.h>
33
34#include <settings/client/settings_client.hpp>
35
36
37namespace sh = nscapi::settings_helper;
38
39FileLogger gFileLogger;
40
41FileLogger::FileLogger() : init_(false) {
42}
43FileLogger::~FileLogger() {
44}
45
46#ifdef WIN32
47#ifndef CSIDL_COMMON_APPDATA
48#define CSIDL_COMMON_APPDATA 0x0023
49#endif
50typedef BOOL (WINAPI *fnSHGetSpecialFolderPath)(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);
51
52__inline BOOL WINAPI _SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate) {
53        static fnSHGetSpecialFolderPath __SHGetSpecialFolderPath = NULL;
54        if (!__SHGetSpecialFolderPath) {
55                HMODULE hDLL = LoadLibrary(_T("shfolder.dll"));
56                if (hDLL != NULL)
57                        __SHGetSpecialFolderPath = (fnSHGetSpecialFolderPath)GetProcAddress(hDLL,"SHGetSpecialFolderPathW");
58        }
59        if(__SHGetSpecialFolderPath)
60                return __SHGetSpecialFolderPath(hwndOwner, lpszPath, nFolder, fCreate);
61        return FALSE;
62}
63#endif
64
65std::wstring getFolder(std::wstring key) {
66        if (key == _T("exe")) {
67                return GET_CORE()->getBasePath();
68        } else {
69#ifdef WIN32
70                if (key == _T("local-app-data")) {
71                        wchar_t buf[MAX_PATH+1];
72                        _SHGetSpecialFolderPath(NULL, buf, CSIDL_COMMON_APPDATA, FALSE);
73                        return buf;
74                }
75#endif
76        }
77        return GET_CORE()->getBasePath();
78}
79std::string FileLogger::getFileName() {
80        if (file_.empty()) {
81                file_ = utf8::cvt<std::string>(cfg_file_);
82                if (file_.empty())
83                        file_ = utf8::cvt<std::string>(setting_keys::log::FILENAME_DEFAULT);
84                if (file_.find("\\") == std::wstring::npos) {
85                        std::string root = utf8::cvt<std::string>(getFolder(cfg_root_));
86                        std::string::size_type pos = root.find_last_not_of('\\');
87                        if (pos != std::wstring::npos) {
88                                //root = root.substr(0, pos);
89                        }
90                        file_ = root + "\\" + file_;
91                }
92        }
93        return file_;
94}
95
96bool FileLogger::loadModule() {
97        return false;
98}
99bool FileLogger::loadModuleEx(std::wstring alias, NSCAPI::moduleLoadMode mode) {
100        //_tzset();
101        try {
102                std::wstring log_mask, file, root;
103
104                sh::settings_registry settings(get_settings_proxy());
105                settings.set_alias(_T("log"), alias);
106
107                settings.alias().add_path_to_settings()
108                        (_T("LOG SECTION"), _T("Configure loggning properties."))
109                        ;
110
111                settings.alias().add_key_to_settings()
112                        //(_T("debug"), sh::bool_key(&debug_, false),
113                        //_T("DEBUG LOGGING"), _T("Enable debug logging can help track down errors and find problems but will impact overall performance negativly."))
114
115                        (_T("log mask"), sh::wstring_key(&log_mask, _T("false")),
116                        _T("LOG MASK"), _T("The log mask information, error, warning, critical, debug"))
117
118                        (_T("root"), sh::wstring_key(&cfg_root_, _T("auto")),
119                        _T("ROOT"), _T("Set this to use a specific syntax string for all commands (that don't specify one)."))
120
121                        (_T("file name"), sh::wstring_key(&cfg_file_),
122                        _T("FILENAME"), _T("The file to write log data to. If no directory is used this is relative to the NSClient++ binary."))
123
124                        (_T("date format"), sh::string_key(&format_, "%Y-%m-%d %H:%M:%S"),
125                        _T("DATEMASK"), _T("The size of the buffer to use when getting messages this affects the speed and maximum size of messages you can recieve."))
126                        ;
127
128                settings.register_all();
129                settings.notify();
130
131                log_mask_ = nscapi::logging::parse(log_mask);
132
133                getFileName();
134
135        } catch (std::exception &e) {
136                NSC_LOG_ERROR_STD(_T("Exception caught: ") + utf8::cvt<std::wstring>(e.what()));
137                return false;
138        } catch (nscapi::nscapi_exception &e) {
139                NSC_LOG_ERROR_STD(_T("Failed to register command: ") + e.msg_);
140                return false;
141        } catch (...) {
142                NSC_LOG_ERROR_STD(_T("Failed to register command."));
143                return false;
144        }
145        NSC_LOG_MESSAGE_STD(_T("Using logmask: ") + nscapi::logging::to_string(log_mask_));
146        init_ = true;
147        std::string hello = "Starting to log for: " + utf8::cvt<std::string>(GET_CORE()->getApplicationName()) + " - " + utf8::cvt<std::string>(GET_CORE()->getApplicationVersionString());
148        handleMessage(NSCAPI::log, __FILE__, __LINE__, hello);
149        handleMessage(NSCAPI::log, __FILE__, __LINE__, "Log path is: " + file_);
150        return true;
151}
152bool FileLogger::unloadModule() {
153        return true;
154}
155bool FileLogger::hasCommandHandler() {
156        return false;
157}
158bool FileLogger::hasMessageHandler() {
159        return true;
160}
161/*
162HANDLE openAppendOrNew(std::wstring file) {
163        DWORD numberOfBytesWritten = 0;
164        HANDLE hFile = ::CreateFile(file.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
165        if (hFile == INVALID_HANDLE_VALUE) {
166                hFile = ::CreateFile(file.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
167                if (hFile != INVALID_HANDLE_VALUE) {
168                        WORD wBOM = 0xFEFF;
169                        ::WriteFile(hFile, &wBOM, sizeof(WORD), &numberOfBytesWritten, NULL);
170                }
171        }
172        return hFile;
173}
174        if (hFile == INVALID_HANDLE_VALUE) {
175                hFile = ::CreateFile(file.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
176                if (hFile != INVALID_HANDLE_VALUE) {
177                        WORD wBOM = 0xFEFF;
178                        ::WriteFile(hFile, &wBOM, sizeof(WORD), &numberOfBytesWritten, NULL);
179        }
180        return hFile;
181}
182*/
183
184void FileLogger::handleMessage(int msgType, const std::string file, int line, std::string message) {
185        if (!init_) {
186                std::wcout << _T("Discarding: ") << utf8::cvt<std::wstring>(message) << std::endl;
187                return;
188        }
189        if (!nscapi::logging::matches(log_mask_, msgType))
190                return;
191
192        std::ofstream stream(file_.c_str(), std::ios::out|std::ios::app|std::ios::ate);
193        if (!stream) {
194                std::wcout << _T("File could not be opened, Discarding: ") << utf8::cvt<std::wstring>(message) << std::endl;
195        }
196        stream << utf8::cvt<std::string>(get_formated_date())
197                << (": ") << utf8::cvt<std::string>(nscapi::plugin_helper::translateMessageType(msgType))
198                << (":") << file
199                <<(":") << line
200                << (": ") << message << std::endl;
201}
202
203std::wstring FileLogger::get_formated_date() {
204        std::wstringstream ss;
205        boost::posix_time::time_facet *facet = new boost::posix_time::time_facet(format_.c_str());
206        ss.imbue(std::locale(std::cout.getloc(), facet));
207        ss << boost::posix_time::second_clock::local_time();
208        return ss.str();
209}
210
211NSC_WRAP_DLL();
212NSC_WRAPPERS_MAIN_DEF(gFileLogger);
213NSC_WRAPPERS_HANDLE_MSG_DEF(gFileLogger);
214NSC_WRAPPERS_IGNORE_CMD_DEF();
Note: See TracBrowser for help on using the repository browser.