Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
jlib
Commits
7a17ff02
Commit
7a17ff02
authored
Sep 23, 2019
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
basic log
parent
bfb60af5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
126 additions
and
45 deletions
+126
-45
logging.h
jlib/base/logging.h
+84
-17
logstream.h
jlib/base/logstream.h
+7
-6
timezone.h
jlib/base/timezone.h
+22
-22
test_logging.cpp
test/test_logging/test_logging.cpp
+12
-0
test_logging.vcxproj
test/test_logging/test_logging.vcxproj
+1
-0
No files found.
jlib/base/logging.h
View file @
7a17ff02
...
@@ -3,14 +3,13 @@
...
@@ -3,14 +3,13 @@
#include "config.h"
#include "config.h"
#include "logstream.h"
#include "logstream.h"
#include "timestamp.h"
#include "timestamp.h"
#include "timezone.h"
#include "currentthread.h"
#include "currentthread.h"
#include <stdlib.h> // getenv
#include <stdlib.h> // getenv
namespace
jlib
namespace
jlib
{
{
class
TimeZone
;
class
Logger
class
Logger
{
{
public
:
public
:
...
@@ -29,13 +28,21 @@ public:
...
@@ -29,13 +28,21 @@ public:
{
{
template
<
int
N
>
template
<
int
N
>
SourceFile
(
const
char
(
&
arr
)[
N
])
:
data_
(
arr
),
size_
(
N
-
1
)
{
SourceFile
(
const
char
(
&
arr
)[
N
])
:
data_
(
arr
),
size_
(
N
-
1
)
{
#ifdef JLIB_WINDOWS
const
char
*
slash
=
strrchr
(
data_
,
'\\'
);
#else
const
char
*
slash
=
strrchr
(
data_
,
'/'
);
const
char
*
slash
=
strrchr
(
data_
,
'/'
);
#endif
if
(
slash
)
{
data_
=
slash
+
1
;
}
if
(
slash
)
{
data_
=
slash
+
1
;
}
size_
-=
static_cast
<
int
>
(
data_
-
arr
);
size_
-=
static_cast
<
int
>
(
data_
-
arr
);
}
}
explicit
SourceFile
(
const
char
*
filename
)
:
data_
(
filename
)
{
explicit
SourceFile
(
const
char
*
filename
)
:
data_
(
filename
)
{
const
char
*
slash
=
strrchr
(
filename
,
'/'
);
#ifdef JLIB_WINDOWS
const
char
*
slash
=
strrchr
(
data_
,
'\\'
);
#else
const
char
*
slash
=
strrchr
(
data_
,
'/'
);
#endif
if
(
slash
)
{
data_
=
slash
+
1
;
}
if
(
slash
)
{
data_
=
slash
+
1
;
}
size_
=
static_cast
<
int
>
(
strlen
(
data_
));
size_
=
static_cast
<
int
>
(
strlen
(
data_
));
}
}
...
@@ -44,19 +51,29 @@ public:
...
@@ -44,19 +51,29 @@ public:
int
size_
;
int
size_
;
};
};
Logger
(
SourceFile
file
,
int
line
);
Logger
(
SourceFile
file
,
int
line
)
:
impl_
(
LogLevel
::
LOGLEVEL_INFO
,
0
,
file
,
line
)
{}
Logger
(
SourceFile
file
,
int
line
,
LogLevel
level
);
Logger
(
SourceFile
file
,
int
line
,
LogLevel
level
)
:
impl_
(
level
,
0
,
file
,
line
)
{}
Logger
(
SourceFile
file
,
int
line
,
LogLevel
level
,
const
char
*
func
);
Logger
(
SourceFile
file
,
int
line
,
LogLevel
level
,
const
char
*
func
)
:
impl_
(
level
,
0
,
file
,
line
)
{
impl_
.
stream_
<<
func
<<
' '
;
}
Logger
(
SourceFile
file
,
int
line
,
bool
toAbort
);
Logger
(
SourceFile
file
,
int
line
,
bool
toAbort
)
:
impl_
(
toAbort
?
LogLevel
::
LOGLEVEL_FATAL
:
LOGLEVEL_ERROR
,
errno
,
file
,
line
)
{}
~
Logger
();
~
Logger
()
{
impl_
.
finish
();
const
auto
&
buf
=
impl_
.
stream_
.
buffer
();
outputFunc_
(
buf
.
data
(),
buf
.
length
());
if
(
impl_
.
level_
==
LOGLEVEL_FATAL
)
{
flushFunc_
();
abort
();
}
}
LogStream
&
stream
()
{
return
impl_
.
stream_
;
}
LogStream
&
stream
()
{
return
impl_
.
stream_
;
}
static
LogLevel
logLevel
()
{
return
logLevel_
;
}
static
LogLevel
logLevel
()
{
return
logLevel_
;
}
static
void
setLogLevel
(
LogLevel
level
)
;
static
void
setLogLevel
(
LogLevel
level
)
{
logLevel_
=
level
;
}
typedef
void
(
*
OutputFunc
)(
const
char
*
msg
,
int
len
);
typedef
void
(
*
OutputFunc
)(
const
char
*
msg
,
int
len
);
typedef
void
(
*
FlushFunc
)();
typedef
void
(
*
FlushFunc
)();
static
void
setOutput
(
OutputFunc
);
static
void
setOutput
(
OutputFunc
);
static
void
setFlush
(
FlushFunc
);
static
void
setFlush
(
FlushFunc
);
static
void
setTimeZone
(
const
TimeZone
&
tz
);
static
void
setTimeZone
(
const
TimeZone
&
tz
);
...
@@ -79,24 +96,41 @@ private:
...
@@ -79,24 +96,41 @@ private:
SourceFile
basename_
;
SourceFile
basename_
;
};
};
static
OutputFunc
outputFunc_
;
static
FlushFunc
flushFunc_
;
static
LogLevel
logLevel_
;
static
LogLevel
logLevel_
;
static
TimeZone
timeZone_
;
Impl
impl_
;
Impl
impl_
;
};
};
static
void
defaultOutput
(
const
char
*
msg
,
int
len
)
{
fwrite
(
msg
,
1
,
len
,
stdout
);
}
/******** log micros *********/
static
void
defaultFlush
()
{
fflush
(
stdout
);
}
static
Logger
::
OutputFunc
g_output
=
defaultOutput
;
#define LOG_TRACE if (jlib::Logger::logLevel() <= jlib::Logger::LogLevel::LOGLEVEL_TRACE) \
static
Logger
::
FlushFunc
g_flush
=
defaultFlush
;
jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_TRACE, __func__).stream()
#define LOG_DEBUG if (jlib::Logger::logLevel() <= jlib::Logger::LogLevel::LOGLEVEL_DEBUG) \
jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_DEBUG, __func__).stream()
#define LOG_INFO if (jlib::Logger::logLevel() <= jlib::Logger::LogLevel::LOGLEVEL_INFO) \
jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_INFO).stream()
#define LOG_WARN jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_WARN).stream()
#define LOG_ERROR jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_ERROR).stream()
#define LOG_FATAL jlib::Logger(__FILE__, __LINE__, jlib::Logger::LogLevel::LOGLEVEL_FATAL).stream()
#define LOG_SYSERR jlib::Logger(__FILE__, __LINE__, false).stream()
#define LOG_SYSFATAL jlib::Logger(__FILE__, __LINE__, true).stream()
namespace
detail
namespace
detail
{
{
static
const
char
*
LogLevelName
[
Logger
::
LogLevel
::
LOGLEVEL_COUNT
]
=
static
void
defaultOutput
(
const
char
*
msg
,
int
len
)
{
fwrite
(
msg
,
1
,
len
,
stdout
);
}
{
static
void
defaultFlush
()
{
fflush
(
stdout
);
}
static
const
char
*
LogLevelName
[
Logger
::
LogLevel
::
LOGLEVEL_COUNT
]
=
{
"TRACE "
,
"TRACE "
,
"DEBUG "
,
"DEBUG "
,
"INFO "
,
"INFO "
,
...
@@ -131,11 +165,20 @@ struct T
...
@@ -131,11 +165,20 @@ struct T
thread_local
char
t_errnobuf
[
512
]
=
{
0
};
thread_local
char
t_errnobuf
[
512
]
=
{
0
};
thread_local
char
t_time
[
64
]
=
{
0
};
thread_local
char
t_time
[
64
]
=
{
0
};
thread_local
time_t
t_lastSecond
=
0
;
thread_local
time_t
t_lastSecond
=
0
;
static
constexpr
unsigned
int
T_TIME_STR_LEN
=
17
;
}
// detail
}
// detail
/******** static initializer *********/
Logger
::
OutputFunc
Logger
::
outputFunc_
=
detail
::
defaultOutput
;
Logger
::
FlushFunc
Logger
::
flushFunc_
=
detail
::
defaultFlush
;
Logger
::
LogLevel
Logger
::
logLevel_
=
detail
::
initLogLevel
();
Logger
::
LogLevel
Logger
::
logLevel_
=
detail
::
initLogLevel
();
TimeZone
Logger
::
timeZone_
=
{};
/******** LogStream operators *********/
inline
LogStream
&
operator
<<
(
LogStream
&
s
,
const
Logger
::
SourceFile
&
f
)
{
inline
LogStream
&
operator
<<
(
LogStream
&
s
,
const
Logger
::
SourceFile
&
f
)
{
s
.
append
(
f
.
data_
,
f
.
size_
);
return
s
;
s
.
append
(
f
.
data_
,
f
.
size_
);
return
s
;
...
@@ -151,6 +194,8 @@ static const char* strerror_t(int savedErrno) {
...
@@ -151,6 +194,8 @@ static const char* strerror_t(int savedErrno) {
}
}
/******** Logger::Impl *********/
Logger
::
Impl
::
Impl
(
LogLevel
level
,
int
old_errno
,
const
SourceFile
&
file
,
int
line
)
Logger
::
Impl
::
Impl
(
LogLevel
level
,
int
old_errno
,
const
SourceFile
&
file
,
int
line
)
:
time_
(
Timestamp
::
now
())
:
time_
(
Timestamp
::
now
())
,
stream_
()
,
stream_
()
...
@@ -170,12 +215,34 @@ Logger::Impl::Impl(LogLevel level, int old_errno, const SourceFile& file, int li
...
@@ -170,12 +215,34 @@ Logger::Impl::Impl(LogLevel level, int old_errno, const SourceFile& file, int li
void
Logger
::
Impl
::
formatTime
()
void
Logger
::
Impl
::
formatTime
()
{
{
int64_t
microSecsSinceEpoch
=
time_
.
microSecondsSinceEpoch
();
int64_t
microSecsSinceEpoch
=
time_
.
microSecondsSinceEpoch
();
time_t
seconds
=
static_cast
<
time_t
>
(
microSecsSinceEpoch
/
Timestamp
::
MICRO_SECONDS_PER_SECOND
);
time_t
seconds
=
static_cast
<
time_t
>
(
microSecsSinceEpoch
/
MICRO_SECONDS_PER_SECOND
);
int
microsecs
=
static_cast
<
int
>
(
microSecsSinceEpoch
%
Timestamp
::
MICRO_SECONDS_PER_SECOND
);
int
microsecs
=
static_cast
<
int
>
(
microSecsSinceEpoch
%
MICRO_SECONDS_PER_SECOND
);
if
(
seconds
!=
detail
::
t_lastSecond
)
{
if
(
seconds
!=
detail
::
t_lastSecond
)
{
detail
::
t_lastSecond
=
seconds
;
detail
::
t_lastSecond
=
seconds
;
struct
tm
tm_time
;
if
(
timeZone_
.
valid
())
{
// TODO
}
else
{
gmtime_r
(
&
seconds
,
&
tm_time
);
}
int
len
=
snprintf
(
detail
::
t_time
,
sizeof
(
detail
::
t_time
),
"%4d%02d%02d %02d:%02d:%02d"
,
tm_time
.
tm_year
+
1900
,
tm_time
.
tm_mon
+
1
,
tm_time
.
tm_mday
,
tm_time
.
tm_hour
,
tm_time
.
tm_min
,
tm_time
.
tm_sec
);
assert
(
len
==
detail
::
T_TIME_STR_LEN
);
(
void
)
len
;
}
}
if
(
timeZone_
.
valid
())
{
// TODO
}
else
{
Format
us
(
".%06dZ "
,
microsecs
);
assert
(
us
.
length
()
==
9
);
stream_
<<
detail
::
T
(
detail
::
t_time
,
detail
::
T_TIME_STR_LEN
)
<<
detail
::
T
(
us
.
data
(),
9
);
}
}
void
Logger
::
Impl
::
finish
()
{
stream_
<<
" - "
<<
basename_
<<
':'
<<
line_
<<
'\n'
;
}
}
...
...
jlib/base/logstream.h
View file @
7a17ff02
...
@@ -346,14 +346,15 @@ static std::string formatSI(int64_t s)
...
@@ -346,14 +346,15 @@ static std::string formatSI(int64_t s)
*/
*/
static
std
::
string
formatIEC
(
int64_t
s
)
static
std
::
string
formatIEC
(
int64_t
s
)
{
{
static
constexpr
double
Ki
=
1024
.
0
;
static
constexpr
double
Mi
=
Ki
*
1024
.
0
;
static
constexpr
double
Gi
=
Mi
*
1024
.
0
;
static
constexpr
double
Ti
=
Gi
*
1024
.
0
;
static
constexpr
double
Pi
=
Ti
*
1024
.
0
;
static
constexpr
double
Ei
=
Pi
*
1024
.
0
;
double
n
=
static_cast
<
double
>
(
s
);
double
n
=
static_cast
<
double
>
(
s
);
char
buf
[
64
];
char
buf
[
64
];
const
double
Ki
=
1024
.
0
;
const
double
Mi
=
Ki
*
1024
.
0
;
const
double
Gi
=
Mi
*
1024
.
0
;
const
double
Ti
=
Gi
*
1024
.
0
;
const
double
Pi
=
Ti
*
1024
.
0
;
const
double
Ei
=
Pi
*
1024
.
0
;
if
(
n
<
Ki
)
if
(
n
<
Ki
)
snprintf
(
buf
,
sizeof
buf
,
"%"
PRId64
,
s
);
snprintf
(
buf
,
sizeof
buf
,
"%"
PRId64
,
s
);
...
...
jlib/base/timezone.h
View file @
7a17ff02
...
@@ -71,46 +71,46 @@ struct LocalTime
...
@@ -71,46 +71,46 @@ struct LocalTime
static
constexpr
int
SECONDS_PER_DAY
=
24
*
60
*
60
;
static
constexpr
int
SECONDS_PER_DAY
=
24
*
60
*
60
;
//! TimeZone for 1970~2030
//! TimeZone for 1970~2030
class
Time
z
one
:
public
copyable
class
Time
Z
one
:
public
copyable
{
{
public
:
public
:
explicit
Time
z
one
(
const
char
*
zonename
)
{
explicit
Time
Z
one
(
const
char
*
zonename
)
{
}
}
Time
z
one
(
int
bias
,
const
char
*
tzname
)
{
Time
Z
one
(
int
bias
,
const
char
*
tzname
)
{
}
}
Time
z
one
()
=
default
;
// invalid timezone
Time
Z
one
()
=
default
;
// invalid timezone
bool
valid
()
const
{
bool
valid
()
const
{
return
static_cast
<
bool
>
(
data_
);
return
static_cast
<
bool
>
(
data_
);
}
}
struct
tm
toLocalTime
(
time_t
secondsSinceEpoch
)
const
{
//
struct tm toLocalTime(time_t secondsSinceEpoch) const {
}
//
}
time_t
fromLocalTime
(
const
struct
tm
&
tm_time
)
const
{
//
time_t fromLocalTime(const struct tm& tm_time) const {
}
//
}
static
struct
tm
toUtcTime
(
time_t
secondsSinceEpoch
,
bool
yday
=
false
);
//
static struct tm toUtcTime(time_t secondsSinceEpoch, bool yday = false);
static
time_t
fromUtcTime
(
const
struct
tm
&
tm_time
);
//
static time_t fromUtcTime(const struct tm& tm_time);
//
/**
/
//
**
* @param year [1900, 2500]
//
* @param year [1900, 2500]
* @param month [1, 12]
//
* @param month [1, 12]
* @param day [1, 31]
//
* @param day [1, 31]
* @param hour [0, 23]
//
* @param hour [0, 23]
* @param minute [0, 59]
//
* @param minute [0, 59]
* @param seconds [0, 59]
//
* @param seconds [0, 59]
*/
//
*/
static
time_t
fromUtcTime
(
int
year
,
int
month
,
int
day
,
//
static time_t fromUtcTime(int year, int month, int day,
int
hour
,
int
minute
,
int
seconds
)
{
//
int hour, int minute, int seconds) {
}
//
}
struct
Data
{
struct
Data
{
std
::
vector
<
detail
::
Transition
>
transitions
;
std
::
vector
<
detail
::
Transition
>
transitions
;
...
...
test/test_logging/test_logging.cpp
View file @
7a17ff02
#include "../../jlib/base/logging.h"
#include "../../jlib/base/logging.h"
using
namespace
jlib
;
int
main
()
int
main
()
{
{
Logger
::
setLogLevel
(
Logger
::
LOGLEVEL_TRACE
);
LOG_TRACE
<<
"trace"
;
LOG_DEBUG
<<
"debug"
;
LOG_INFO
<<
"Hello"
;
LOG_WARN
<<
"World"
;
LOG_ERROR
<<
"Error"
;
LOG_INFO
<<
sizeof
(
Logger
);
LOG_INFO
<<
sizeof
(
LogStream
);
LOG_INFO
<<
sizeof
(
Format
);
LOG_INFO
<<
sizeof
(
LogStream
::
Buffer
);
}
}
\ No newline at end of file
test/test_logging/test_logging.vcxproj
View file @
7a17ff02
...
@@ -88,6 +88,7 @@
...
@@ -88,6 +88,7 @@
<Optimization>
Disabled
</Optimization>
<Optimization>
Disabled
</Optimization>
<SDLCheck>
true
</SDLCheck>
<SDLCheck>
true
</SDLCheck>
<ConformanceMode>
true
</ConformanceMode>
<ConformanceMode>
true
</ConformanceMode>
<AdditionalIncludeDirectories>
$(BOOST);%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
</ClCompile>
</ClCompile>
<Link>
<Link>
<SubSystem>
Console
</SubSystem>
<SubSystem>
Console
</SubSystem>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment