This URL has Read-Only access.

Statistics
| Branch: | Tag: | Revision:

root / src / util / logWriter.cpp @ 36397e7c

History | View | Annotate | Download (5.8 kB)

1
/* logWriter.cpp
2
 * Copyright (C) 2008-2009 Société des arts technologiques (SAT)
3
 * http://www.sat.qc.ca
4
 * All rights reserved.
5
 *
6
 * This file is part of [propulse]ART.
7
 *
8
 * [propulse]ART is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * [propulse]ART is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with [propulse]ART.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22

    
23
#include "logWriter.h"
24

    
25
#include <iostream>
26
#include <ctime>
27
#include <sstream>
28

    
29
#ifdef CONFIG_DEBUG_LOCAL
30
#define LOG_LEVEL DEBUG
31
#else
32
#define LOG_LEVEL INFO
33
#endif
34

    
35
bool logLevelIsValid(LogLevel level)
36
{
37
    switch (level)
38
    {
39
        case DEBUG:
40
        case INFO:
41
        case PRINT:
42
        case WARNING:
43
        case ERROR:
44
        case THROW: 
45
        case CRITICAL:
46
        case ASSERT_FAIL:
47
            return true;
48
            break;
49
        default:
50
            return false;
51
            break;
52
    }
53
}
54

    
55
#ifdef COLOR_OUTPUT
56
std::string logLevelStr(LogLevel level)
57
{
58
    std::string lstr;
59
    switch (level)
60
    {
61
        case DEBUG:
62
            lstr = "\r\x1b[19C\x1b[32mDEBUG";
63
            break;
64
        case INFO:
65
            lstr = "\r\x1b[19C\x1b[34mINFO";
66
            break;
67
        case THROW:
68
            lstr = "\r\x1b[19C\x1b[33mTHROW";
69
            break;
70
        case WARNING:
71
            lstr = "\r\x1b[19C\x1b[33mWARNING";
72
            break;
73
        case ERROR:
74
            lstr = "\r\x1b[19C\x1b[31mERROR";
75
            break;
76
        case CRITICAL:
77
            lstr = "\r\x1b[19C\x1b[41mCRITICAL";
78
            break;
79
        case ASSERT_FAIL:
80
            lstr = "\r\x1b[19C\x1b[41mASSERT_FAIL";
81
            break;
82
        default:
83
            lstr = "INVALID LOG LEVEL";
84
    }
85
    lstr += "\x1b[0m: ";
86
    return lstr;
87
}
88
#else
89
std::string logLevelStr(LogLevel level)
90
{
91
    std::string lstr;
92
    switch (level)
93
    {
94
        case DEBUG:
95
            lstr = "DEBUG";
96
            break;
97
        case INFO:
98
            lstr = "INFO";
99
            break;
100
        case THROW:
101
            lstr = "THROW";
102
            break;
103
        case WARNING:
104
            lstr = "WARNING";
105
            break;
106
        case ERROR:
107
            lstr = "ERROR";
108
            break;
109
        case CRITICAL:
110
            lstr = "CRITICAL";
111
            break;
112
        case ASSERT_FAIL:
113
            lstr = "ASSERT_FAIL";
114
            break;
115
        default:
116
            lstr = "INVALID LOG LEVEL";
117
    }
118
    return lstr;
119
}
120
#endif
121

    
122
static Log::Subscriber emptyLogSubscriber;
123
static Log::Subscriber* lf = &emptyLogSubscriber;
124
static bool hold_flag = false;
125

    
126

    
127
Log::Subscriber::~Subscriber()
128
{
129
    lf = &emptyLogSubscriber;
130
}
131

    
132

    
133
void Log::Subscriber::hold()
134
{
135
    hold_flag = true;
136
}
137

    
138

    
139
void Log::Subscriber::enable()
140
{
141
    hold_flag = false;
142
}
143

    
144
Log::Subscriber::Subscriber()
145
{
146
    lf = this;
147
}
148

    
149
bool xlogLevelMatch(LogLevel level)
150
{
151
    if (level >= LOG_LEVEL && logLevelIsValid(level))
152
        return true;
153
    else
154
        return false;
155
}
156

    
157
#include<iomanip>
158
#include<boost/date_time/posix_time/posix_time.hpp>
159
std::string log_(const std::string &msg, LogLevel level, const std::string &fileName,
160
                const std::string &/*functionName*/, int lineNum)
161
{
162
    using namespace boost::posix_time;
163
    std::ostringstream logMsg;
164
    if (level == PRINT) // for normal printing without log formatting
165
    {
166
        logMsg << msg;
167
        return logMsg.str();
168
    }
169

    
170
#ifdef CONFIG_DEBUG_LOCAL
171
    //ptime now = microsec_clock::local_time();
172
    if(level >= INFO and level < WARNING)
173
        logMsg << logLevelStr(level) << ":" << msg << std::endl;
174
    else
175
        logMsg << fileName << ":" << 
176
            lineNum << ":" << logLevelStr(level) << ":" << msg << std::endl;
177
#else
178
    logMsg <<  logLevelStr(level) << ":" << msg <<  std::endl;
179
#endif
180

    
181
    return logMsg.str();
182
}
183

    
184
//TODO DOCUMENT THIS
185
void cerr_log_throw( const std::string &msg, LogLevel level, const std::string &fileName,
186
        const std::string &functionName, int lineNum,int err)
187
{
188
    std::string strerr = log_(msg, level, fileName, functionName, lineNum);
189

    
190
    if(err == -1) //TODO Is this used?
191
        throw(Except(msg.c_str(), 0));
192

    
193
    if (!hold_flag)//TODO check logger  
194
        (*lf)(level, strerr);
195

    
196
    if (level < THROW)
197
        return;
198

    
199
    if(level < CRITICAL)
200
        throw(ErrorExcept(strerr.c_str(), err));
201
    if(level < ASSERT_FAIL)
202
        throw(CriticalExcept(strerr.c_str()));
203
    throw(AssertExcept(strerr.c_str()));
204

    
205
}
206
#define BACKTRACE
207
#ifdef BACKTRACE
208
#include <signal.h>
209
#include <execinfo.h>
210
#include <cxxabi.h>
211
#include <dlfcn.h>
212
#include <stdlib.h>
213

    
214
void backtrace()
215
{
216
    void *trace[16];
217
    char **messages = (char **)NULL;
218
    int status, i, trace_size = 0;
219
    Dl_info dlinfo;
220
    const char *symname;
221
    char *demangled;
222

    
223
    trace_size = backtrace(trace, 16);
224
    messages = backtrace_symbols(trace, trace_size);
225
    for (i=0; i < trace_size; ++i)
226
    {
227
        if(!dladdr(trace[i], &dlinfo))
228
            continue;
229

    
230
        symname = dlinfo.dli_sname;
231
        demangled = abi::__cxa_demangle(symname, NULL, 0, &status);
232
        if(status == 0 && demangled)
233
            symname = demangled;
234

    
235
        std::cerr << "object:" << dlinfo.dli_fname << " function:" <<  symname << std::endl;
236

    
237
        if (demangled)
238
            free(demangled);
239
    }
240
}
241
#else
242
void backtrace(){}
243
#endif
244
void assert_throw(__const char *__assertion, __const char *__file,
245
        unsigned int __line, __const char *__function)
246
{
247
    backtrace();
248
    cerr_log_throw(__assertion, ASSERT_FAIL, __file, __function, __line, 0);
249
}