Skip to content

Commit

Permalink
logger: Provide stat with number of log messages
Browse files Browse the repository at this point in the history
  • Loading branch information
shramov committed Dec 26, 2024
1 parent 9c105b8 commit cb9a773
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/ld.script
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,5 @@ TLL_0.3.0 {
TLL_0.4.0 {
global:
tll_config_value_dup;
tll_logger_stat;
} TLL_0.3.0;
54 changes: 52 additions & 2 deletions src/logger/logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "tll/config.h"
#include "tll/logger.h"
#include "tll/logger/impl.h"
#include "tll/stat.h"
#include "tll/util/refptr.h"
#include "tll/util/size.h"
#include "tll/util/string.h"
Expand All @@ -33,12 +34,25 @@

namespace tll::logger {

struct Stat
{
tll::stat::Integer<tll::stat::Sum, tll::stat::Unknown, 't', 'o', 't', 'a', 'l'> total; //< All log entries
tll::stat::Integer<tll::stat::Sum, tll::stat::Unknown, 'w', 'a', 'r', 'n'> warn; //< Warning messages
tll::stat::Integer<tll::stat::Sum, tll::stat::Unknown, 'e', 'r', 'r', 'o', 'r'> error; //< Error or crit

/// Amount of overflows, messages that can not be pushed to async thread
tll::stat::Integer<tll::stat::Sum, tll::stat::Unknown, 'o', 'v', 'e', 'r', 'f', 'l', 'w'> overflow;
};

struct logger_context_t
{
std::shared_mutex lock;
typedef std::unique_lock<std::shared_mutex> wlock_t;
typedef std::shared_lock<std::shared_mutex> rlock_t;

bool _stat_enable = true;
tll::stat::Block<Stat> _stat = { "tll.logger" };

std::unique_ptr<Thread> _thread;

std::map<std::string_view, Logger *, std::less<>> _loggers;
Expand All @@ -55,6 +69,24 @@ struct logger_context_t
_thread.reset();
}

tll_stat_block_t * stat()
{
if (_stat_enable)
return &_stat;
return nullptr;
}

template <typename F, typename ... Args>
void stat_apply(F func, Args ... args)
{
if (!_stat_enable)
return;
if (auto p = _stat.acquire_wait(); p) {
func(p, std::forward<Args>(args)...);
_stat.release(p);
}
}

Logger * init(std::string_view name)
{
{
Expand Down Expand Up @@ -200,6 +232,8 @@ struct logger_context_t

int configure(const tll::ConstConfig &cfg)
{
_stat_enable = cfg.getT<bool>("stat").value_or(false);

if (auto levels = cfg.sub("levels"); levels) {
std::set<std::string> skip;
for (auto & [k, v] : levels->browse("**", true)) {
Expand Down Expand Up @@ -313,6 +347,7 @@ const char * tll_logger_name(const tll_logger_t * log)

int tll_logger_log(tll_logger_t * l, tll_logger_level_t level, const char * buf, size_t len)
{
using namespace tll::logger;
auto log = static_cast<tll::logger::Logger *>(l);
if (log->level > level) return 0;

Expand All @@ -322,8 +357,18 @@ int tll_logger_log(tll_logger_t * l, tll_logger_level_t level, const char * buf,

auto ts = tll::time::now();

if (tll::logger::context._thread) {
return tll::logger::context._thread->push(log, ts, level, {buf, len});
context.stat_apply([](auto p, auto level) {
p->total = 1;
if (level == tll::Logger::Warning) {
p->warn = 1;
} else if (level > tll::Logger::Warning) {
p->error = 1;
}
}, level);
if (context._thread) {
if (context._thread->push(log, ts, level, {buf, len}))
context.stat_apply([](auto p) { p->overflow = 1; });
return 0;
} else
return log->impl->log(ts, level, {buf, len});
}
Expand Down Expand Up @@ -372,3 +417,8 @@ int tll_logger_printf(tll_logger_t * l, tll_logger_level_t level, const char * f

return tll_logger_log(l, level, buf->data(), r);
}

tll_stat_block_t * tll_logger_stat()
{
return tll::logger::context.stat();
}
10 changes: 8 additions & 2 deletions src/tll/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,20 @@ typedef struct {
*/
tll_logger_t * tll_logger_new(const char * name, int len);

//< Free logger object
/// Free logger object
void tll_logger_free(tll_logger_t * log);

//< Create copy of logger object, effectively it's same pointer with increased reference
/// Create copy of logger object, effectively it's same pointer with increased reference
tll_logger_t * tll_logger_copy(const tll_logger_t * log);

int tll_logger_config(const struct tll_config_t * cfg);

struct tll_stat_block_t;
/** Get stat block for logger
* @return pointer to stat block if it is enabled, otherwise NULL
*/
struct tll_stat_block_t * tll_logger_stat();

/**
* Set logging level for specified path
* If name is empty ("") then default logging level is changed.
Expand Down

0 comments on commit cb9a773

Please sign in to comment.