source: cpp/common/loggers/loggers.cpp @ 1299

Last change on this file since 1299 was 1215, checked in by Maciej Komosinski, 20 months ago

Less ambiguous names of counting functions in loggers: warning -> error_warning, info -> error_warning_info

  • Property svn:eol-style set to native
File size: 4.5 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[874]2// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]4
[375]5#include "loggers.h"
[841]6#include <common/util-string.h>
[511]7#include <string.h>
[109]8
[511]9void logMessage(const char *obj, const char *method, int level, const char *msg)
[109]10{
[378]11        tlsGetRef(message_handler_manager_instance).send(obj, method, level, msg);
[109]12}
13
[375]14THREAD_LOCAL_DEF(LoggerManager, message_handler_manager_instance);
[109]15
[378]16void LoggerManager::send(int position, const char *obj, const char *method, int level, const char *msg)
[109]17{
[1075]18        if (position >= int(loggers.size())) position = int(loggers.size()) - 1;
[378]19        bool blocked = false;
20        for (int i = position; i >= 0; i--)
[109]21        {
[378]22                LoggerBase *logger = loggers[i];
23                if ((!(logger->options & LoggerBase::Paused)) &&
24                        ((!blocked) || (logger->options & LoggerBase::CannotBeBlocked)))
[336]25                {
[378]26                        logger->handle(obj, method, level, msg);
27                        if (!(logger->options & LoggerBase::DontBlock)) blocked = true;
[336]28                }
[109]29        }
30}
31
[378]32int LoggerManager::add(LoggerBase *logger)
[109]33{
[378]34        logger->manager = this;
35        loggers.push_back(logger);
[1075]36        return int(loggers.size()) - 1;
[109]37}
38
[375]39void LoggerManager::remove(int i)
[109]40{
[378]41        LoggerBase *h = loggers[i];
[373]42        h->manager = NULL;
[378]43        loggers.erase(loggers.begin() + i);
[109]44}
45
[378]46void LoggerManager::remove(LoggerBase *logger)
[109]47{
[378]48        int index = find(logger);
49        if (index >= 0)
50                remove(index);
[109]51}
52
[375]53void LoggerManager::removeAll()
[109]54{
[378]55        while (loggers.size() > 0)
[1075]56                remove(int(loggers.size()) - 1);
[109]57}
58
59//////////////////////////////////
60
[378]61void LoggerBase::send(const char *obj, const char *method, int level, const char *msg)
[109]62{
[336]63        if (!isEnabled()) return;
[378]64        int position = manager->find(this);
65        if (position >= 0) manager->send(position - 1, obj, method, level, msg);
[109]66}
67
[378]68void LoggerBase::logPrintf(const char *obj, const char *method, int level, const char *msg, ...)
[109]69{
[336]70        if (!isEnabled()) return;
71        string buf;
72        va_list argptr;
[378]73        va_start(argptr, msg);
74        buf = ssprintf_va(msg, argptr);
[336]75        va_end(argptr);
[378]76        send(obj, method, level, buf.c_str());
[109]77}
78
79
[375]80void LoggerBase::enable()
[109]81{
[336]82        if (isEnabled()) return;
[372]83        tlsGetRef(message_handler_manager_instance).add(this);
[109]84}
85
[375]86void LoggerBase::disable()
[109]87{
[336]88        if (!isEnabled()) return;
[372]89        tlsGetRef(message_handler_manager_instance).remove(this);
[109]90}
91
[375]92void LoggerBase::pause()
[336]93{
94        if (isPaused()) return;
95        options |= Paused;
96}
97
[375]98void LoggerBase::resume()
[336]99{
100        if (!isPaused()) return;
101        options &= ~Paused;
102}
103
[511]104void LoggerBase::handle(const char *obj, const char *method, int level, const char *msg)
105{
106        int line = 0; //all lines except the first one get the "..." prefix
107        const char* nextsep;
108        do
109        {
110                nextsep = strchr(msg, '\n');
111                if (nextsep == NULL) //last chunk, until the end
112                        nextsep = strchr(msg, '\0');
113                if ((nextsep > msg) && (nextsep[-1] == '\r'))
114                        nextsep--;
115                if (line == 0)
116                {
117                        if (*nextsep == 0) //there was only one line! no need to modify it in any way.
118                                handleSingleLine(obj, method, level, msg);
119                        else //first line from multi-line
120                                handleSingleLine(obj, method, level, string(msg, nextsep - msg).c_str());
121                }
122                else //consecutive lines from multi-line
123                        handleSingleLine(obj, method, level, (LOG_MULTILINE_CONTINUATION + string(msg, nextsep - msg)).c_str()); //could also add line numbers like ...(3)... but let's keep the prefix short and simple
124                line++;
[873]125                if ((options & Paused) != 0) break; //seemingly pointless test (it was already checked), but 'options' can change inside handleSingleLine().
[511]126                if ((nextsep[0] == '\r') && (nextsep[1] == '\n'))
127                        msg = nextsep + 2;
128                else if (*nextsep)
129                        msg = nextsep + 1;
130        } while (*nextsep);
131}
132
[109]133/////////////////////////////////
134
[378]135void LoggerToMemory::handle(const char *obj, const char *method, int level, const char *msg)
[109]136{
[378]137        if (level > maxlevel) maxlevel = level;
138        if (level >= LOG_INFO) infocount++;
139        if (level >= LOG_WARN) warncount++;
140        if (level >= LOG_ERROR) errcount++;
[109]141
[378]142        if (level >= minleveltostore)
[109]143        {
[373]144                storedcount++;
[336]145                if (options & (StoreFirstMessage | StoreAllMessages))
[109]146                {
[378]147                        if (!((options&StoreFirstMessage) && (msgs.length() > 0)))
[109]148                        {
[378]149                                if (msgs.length() > 0) msgs += '\n';
[874]150                                msgs += ssprintf(LOG_FORMAT, logLevelName(level), obj, method, msg);
[109]151                        }
152                }
153        }
154}
[452]155
156string LoggerToMemory::getCountSummary() const
157{
[1215]158        if (getErrorWarningInfoCount())
[452]159        {
[522]160                string msg;
161                if (getErrorCount())
162                        msg = ssprintf("%d error(s)", getErrorCount());
163                int w;
[1215]164                if ((w = getWarningCount()))
165                        msg += ssprintf("%s%d warning(s)", (msg.size()>0 ? ", " : ""), w);
166                if ((w = getInfoCount()))
167                        msg += ssprintf("%s%d message(s)", (msg.size()>0 ? ", " : ""), w);
[522]168                return msg;
[452]169        }
[522]170        return string("");
[452]171}
Note: See TracBrowser for help on using the repository browser.