forked from Haivision/srt
-
Notifications
You must be signed in to change notification settings - Fork 1
/
logsupport.cpp
205 lines (170 loc) · 4.94 KB
/
logsupport.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
* SRT - Secure, Reliable, Transport
* Copyright (c) 2018 Haivision Systems Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <map>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>
#include "logsupport.hpp"
#include "../srtcore/srt.h"
#include "../srtcore/utilities.h"
using namespace std;
// This is based on codes taken from <sys/syslog.h>
// This is POSIX standard, so it's not going to change.
// Haivision standard only adds one more severity below
// DEBUG named DEBUG_TRACE to satisfy all possible needs.
map<string, int> srt_level_names
{
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
{ "debug", LOG_DEBUG },
{ "emerg", LOG_EMERG },
{ "err", LOG_ERR },
{ "error", LOG_ERR }, /* DEPRECATED */
{ "fatal", LOG_CRIT }, // XXX Added for SRT
{ "info", LOG_INFO },
// WTF? Undefined symbol? { "none", INTERNAL_NOPRI }, /* INTERNAL */
{ "notice", LOG_NOTICE },
{ "note", LOG_NOTICE }, // XXX Added for SRT
{ "panic", LOG_EMERG }, /* DEPRECATED */
{ "warn", LOG_WARNING }, /* DEPRECATED */
{ "warning", LOG_WARNING },
//{ "", -1 }
};
srt_logging::LogLevel::type SrtParseLogLevel(string level)
{
using namespace srt_logging;
if ( level.empty() )
return LogLevel::fatal;
if ( isdigit(level[0]) )
{
long lev = strtol(level.c_str(), 0, 10);
if ( lev >= SRT_LOG_LEVEL_MIN && lev <= SRT_LOG_LEVEL_MAX )
return LogLevel::type(lev);
cerr << "ERROR: Invalid loglevel number: " << level << " - fallback to FATAL\n";
return LogLevel::fatal;
}
int (*ToLower)(int) = &std::tolower; // manual overload resolution
transform(level.begin(), level.end(), level.begin(), ToLower);
auto i = srt_level_names.find(level);
if ( i == srt_level_names.end() )
{
cerr << "ERROR: Invalid loglevel spec: " << level << " - fallback to FATAL\n";
return LogLevel::fatal;
}
return LogLevel::type(i->second);
}
struct ToLowerFormat
{
char operator()(char in)
{
if (islower(in))
return in;
if (isupper(in))
return tolower(in);
if (in == '_')
return '-';
throw std::invalid_argument("Wrong FA name - please check the definition in scripts/generate-logging-defs.tcl file");
}
};
void LogFANames::Install(string upname, int value)
{
string id;
transform(upname.begin(), upname.end(), back_inserter(id), ToLowerFormat());
namemap[id] = value;
}
// See logsupport_appdefs.cpp for log FA definitions
LogFANames srt_transmit_logfa_names;
const map<string, int> SrtLogFAList()
{
return srt_transmit_logfa_names.namemap;
}
set<srt_logging::LogFA> SrtParseLogFA(string fa, set<string>* punknown)
{
using namespace srt_logging;
set<LogFA> fas;
// The split algo won't work on empty string.
if ( fa == "" )
return fas;
auto& names = srt_transmit_logfa_names.namemap;
if ( fa == "all" )
{
for (auto entry: names)
{
// Skip "general", it's always on
if (entry.first == "general")
continue;
fas.insert(entry.second);
}
return fas;
}
int (*ToLower)(int) = &std::tolower;
transform(fa.begin(), fa.end(), fa.begin(), ToLower);
vector<string> xfas;
size_t pos = 0, ppos = 0;
for (;;)
{
if ( fa[pos] != ',' )
{
++pos;
if ( pos < fa.size() )
continue;
}
size_t n = pos - ppos;
if ( n != 0 )
xfas.push_back(fa.substr(ppos, n));
++pos;
if ( pos >= fa.size() )
break;
ppos = pos;
}
for (size_t i = 0; i < xfas.size(); ++i)
{
fa = xfas[i];
int* pfa = map_getp(names, fa);
if (!pfa)
{
if (punknown)
punknown->insert(fa); // If requested, add it back silently
else
cerr << "ERROR: Invalid log functional area spec: '" << fa << "' - skipping\n";
continue;
}
fas.insert(*pfa);
}
return fas;
}
void ParseLogFASpec(const vector<string>& speclist, string& w_on, string& w_off)
{
std::ostringstream son, soff;
for (auto& s: speclist)
{
string name;
bool on = true;
if (s[0] == '+')
name = s.substr(1);
else if (s[0] == '~')
{
name = s.substr(1);
on = false;
}
else
name = s;
if (on)
son << "," << name;
else
soff << "," << name;
}
const string& sons = son.str();
const string& soffs = soff.str();
w_on = sons.empty() ? string() : sons.substr(1);
w_off = soffs.empty() ? string() : soffs.substr(1);
}