Skip to content

Commit c4c7922

Browse files
authored
change alog color from string to integer code (alibaba#923)
change alog color from string to integer code, avoid mktime() in throttle_block()
1 parent f728610 commit c4c7922

2 files changed

Lines changed: 76 additions & 75 deletions

File tree

common/alog.cpp

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,76 +37,76 @@ limitations under the License.
3737
#include <vector>
3838
using namespace std;
3939

40+
static uint32_t now0;
4041
static struct tm alog_time = {0};
4142

42-
struct iovec_str : iovec {
43-
template <size_t N>
44-
constexpr iovec_str(const char (&s)[N])
45-
: iovec{const_cast<char*>(s), N - 1} {}
46-
constexpr iovec_str(const char* s, size_t n)
47-
: iovec{const_cast<char*>(s), n} {}
48-
};
49-
50-
constexpr static iovec_str alog_color_reset("\033[0m");
51-
5243
class BaseLogOutput : public ILogOutput {
5344
public:
5445
uint64_t throttle = -1UL;
5546
uint64_t count = 0;
56-
time_t ts = 0;
47+
uint32_t ts = 0;
5748
int log_file_fd;
58-
iovec_str level_prefix[ALOG_AUDIT + 1];
59-
60-
constexpr BaseLogOutput(int fd = 0)
61-
: log_file_fd(fd),
62-
level_prefix{ALOG_COLOR_DARKGRAY, ALOG_COLOR_LIGHTGRAY,
63-
ALOG_COLOR_YELLOW, ALOG_COLOR_RED,
64-
ALOG_COLOR_MAGENTA, ALOG_COLOR_CYAN,
65-
ALOG_COLOR_GREEN} {}
66-
67-
void set_level_color(int level, const char* color, size_t len) override {
68-
if (level < 0 || level > ALOG_AUDIT) return;
69-
level_prefix[level] = {color, len};
49+
constexpr BaseLogOutput(int fd = 0) : log_file_fd(fd) { }
50+
unsigned char level_color[ALOG_AUDIT + 1] = { ALOG_COLOR_DARKGRAY,
51+
ALOG_COLOR_NOTHING, ALOG_COLOR_YELLOW, ALOG_COLOR_RED,
52+
ALOG_COLOR_MAGENTA, ALOG_COLOR_CYAN, ALOG_COLOR_GREEN};
53+
void clear_color() { memset(level_color, 0, sizeof(level_color)); }
54+
uint16_t decode(uint16_t c) {
55+
c = ((c & 0xf) << 8) | (c >> 4);
56+
return c + *(uint16_t*)"00";
57+
}
58+
uint16_t get_color(unsigned int level) {
59+
if (level < LEN(level_color))
60+
if (auto c = level_color[level])
61+
return decode(c);
62+
return 0;
63+
}
64+
int set_level_color(int level, unsigned char code) override {
65+
if ((uint32_t)level > ALOG_AUDIT)
66+
LOG_ERROR_RETURN(EINVAL, -1, "invalid level ", level);
67+
auto dx = decode(code);
68+
if ((dx < decode(ALOG_COLOR_RED) &&
69+
(dx > ALOG_COLOR_NOTHING)) ||
70+
(dx > decode(ALOG_COLOR_LIGHTWHITE)) ||
71+
(dx > decode(ALOG_COLOR_LIGHTGRAY) &&
72+
(dx < decode(ALOG_COLOR_DARKGRAY)))) {
73+
LOG_ERROR_RETURN(EINVAL, -1, "invalid color code ", code);
74+
}
75+
level_color[level] = code;
76+
return 0;
7077
}
7178

7279
struct LineIOV {
7380
struct iovec iov[3];
7481
size_t total_length;
7582
uint8_t iovst, iovcnt;
83+
char color_prefix[6] = "\033[00m";
84+
LineIOV(uint16_t color, const char* begin, const char* end) {
85+
total_length = end - begin;
86+
iov[1] = {(void*)begin, total_length};
87+
if (!color) {
88+
iovst = iovcnt = 1;
89+
} else {
90+
*(uint16_t*)&color_prefix[2] = color;
91+
iov[0] = {color_prefix, LEN(color_prefix) - 1};
92+
constexpr static char color_suffix[] = "\033[0m";
93+
iov[2] = {(void*)color_suffix, LEN(color_suffix) - 1};
94+
total_length += iov[0].iov_len + iov[2].iov_len;
95+
iovst = 0; iovcnt = 3;
96+
}
97+
}
7698
iovec* start() { return iov + iovst; }
7799
int count() { return iovcnt; }
78100
};
79-
LineIOV prepare_line_iov(int level_, const char* begin, const char* end) {
80-
LineIOV iov;
81-
unsigned int level = level_;
82-
iov.total_length = end - begin;
83-
iov.iov[1] = {(void*)begin, iov.total_length};
84-
if (level >= LEN(level_prefix) || 0 == level_prefix[level].iov_len) {
85-
iov.iovst = iov.iovcnt = 1;
86-
} else {
87-
iov.iov[0] = level_prefix[level];
88-
iov.iov[2] = alog_color_reset;
89-
iov.total_length += iov.iov[0].iov_len +
90-
iov.iov[2].iov_len ;
91-
iov.iovst = 0; iov.iovcnt = 3;
92-
}
93-
return iov;
94-
}
95101
void write(int level, const char* begin, const char* end) override {
96-
auto iov = prepare_line_iov(level, begin, end);
102+
LineIOV iov(get_color(level), begin, end);
97103
std::ignore = ::writev(log_file_fd, iov.start(), iov.count());
98104
throttle_block();
99105
}
100106
void throttle_block() {
101107
if (throttle == -1UL) return;
102-
time_t t = mktime(&alog_time);
103-
if (t > ts) {
104-
ts = t;
105-
count = 0;
106-
}
107-
if (++count > throttle) {
108-
std::this_thread::sleep_for(std::chrono::seconds(1));
109-
}
108+
if (ts != now0) { ts = now0; count = 0; }
109+
if (++count > throttle) { ::sleep(1); }
110110
}
111111
virtual int get_log_file_fd() override { return log_file_fd; }
112112
virtual uint64_t set_throttle(uint64_t t = -1) override { return throttle = t; }
@@ -257,8 +257,11 @@ void LogFormatter::put_integer_dec(ALogBuffer& buf, ALogInteger x)
257257
}
258258

259259
__attribute__((constructor)) static void __initial_timezone() { tzset(); }
260-
static time_t dayid = 0, minuteid = 0, tsdelta = 0;
261-
static struct tm* alog_update_time(time_t now0) {
260+
static struct tm* alog_update_time(uint32_t now0) {
261+
static uint32_t dayid = 0, minuteid = 0;
262+
static time_t tsdelta = 0;
263+
::now0 = now0;
264+
262265
auto now = now0 + tsdelta;
263266
int sec = now % 60; now /= 60;
264267
if (unlikely(now != minuteid)) { // calibrate wall time every minute
@@ -481,8 +484,7 @@ class AsyncLogOutput final : public BaseLogOutput {
481484
static thread_local uint64_t index = 0;
482485
auto current = (++index) & (queue_num - 1);
483486
size_t ra;
484-
auto iov = prepare_line_iov(level, begin, end);
485-
{
487+
LineIOV iov(get_color(level), begin, end); {
486488
SCOPED_LOCK(lock[current].get());
487489
ra = buf[current]->read_available();
488490
(void)buf[current]->produce_push_batch_fully(iov.total_length,

common/alog.h

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,27 @@ limitations under the License.
2929
#include <photon/common/conststr.h>
3030
#include <photon/common/retval.h>
3131

32-
#define ALOG_COLOR_BLACK "\033[30m"
33-
#define ALOG_COLOR_RED "\033[31m"
34-
#define ALOG_COLOR_GREEN "\033[32m"
35-
#define ALOG_COLOR_YELLOW "\033[33m"
36-
#define ALOG_COLOR_BLUE "\033[34m"
37-
#define ALOG_COLOR_MAGENTA "\033[35m"
38-
#define ALOG_COLOR_CYAN "\033[36m"
39-
#define ALOG_COLOR_LIGHTGRAY "\033[37m"
40-
#define ALOG_COLOR_DARKGRAY "\033[90m"
41-
#define ALOG_COLOR_LIGHTRED "\033[91m"
42-
#define ALOG_COLOR_LIGHTGREEN "\033[92m"
43-
#define ALOG_COLOR_LIGHTYELLOW "\033[93m"
44-
#define ALOG_COLOR_LIGHTBLUE "\033[94m"
45-
#define ALOG_COLOR_LIGHTMAGENTA "\033[95m"
46-
#define ALOG_COLOR_LIGHTCYAN "\033[96m"
47-
#define ALOG_COLOR_LIGHTWHITE "\033[97m"
48-
#define ALOG_COLOR_NOTHING ""
32+
#define DEFINE_ALOG_COLOR(code, symbol) \
33+
const unsigned char symbol = 0x##code;
34+
DEFINE_ALOG_COLOR(30, ALOG_COLOR_BLACK);
35+
DEFINE_ALOG_COLOR(31, ALOG_COLOR_RED);
36+
DEFINE_ALOG_COLOR(32, ALOG_COLOR_GREEN);
37+
DEFINE_ALOG_COLOR(33, ALOG_COLOR_YELLOW);
38+
DEFINE_ALOG_COLOR(34, ALOG_COLOR_BLUE);
39+
DEFINE_ALOG_COLOR(35, ALOG_COLOR_MAGENTA);
40+
DEFINE_ALOG_COLOR(36, ALOG_COLOR_CYAN);
41+
DEFINE_ALOG_COLOR(37, ALOG_COLOR_LIGHTGRAY);
42+
DEFINE_ALOG_COLOR(90, ALOG_COLOR_DARKGRAY);
43+
DEFINE_ALOG_COLOR(91, ALOG_COLOR_LIGHTRED);
44+
DEFINE_ALOG_COLOR(92, ALOG_COLOR_LIGHTGREEN);
45+
DEFINE_ALOG_COLOR(93, ALOG_COLOR_LIGHTYELLOW);
46+
DEFINE_ALOG_COLOR(94, ALOG_COLOR_LIGHTBLUE);
47+
DEFINE_ALOG_COLOR(95, ALOG_COLOR_LIGHTMAGENTA);
48+
DEFINE_ALOG_COLOR(96, ALOG_COLOR_LIGHTCYAN);
49+
DEFINE_ALOG_COLOR(97, ALOG_COLOR_LIGHTWHITE);
50+
DEFINE_ALOG_COLOR(00, ALOG_COLOR_NOTHING);
51+
#undef DEFINE_ALOG_COLOR
52+
4953

5054
class ILogOutput {
5155
protected:
@@ -59,12 +63,7 @@ class ILogOutput {
5963
virtual uint64_t set_throttle(uint64_t t = -1UL) = 0;
6064
virtual uint64_t get_throttle() = 0;
6165
virtual void destruct() = 0;
62-
template <size_t N>
63-
void set_level_color(int level, const char (&color)[N]) {
64-
set_level_color(level, color, N - 1);
65-
}
66-
virtual void set_level_color(int level, const char* color,
67-
size_t length) { /* ignored by default */ }
66+
virtual int set_level_color(int level, unsigned char code) { return 0; /* ignored by default */ }
6867
void preset_color();
6968
void clear_color();
7069
};

0 commit comments

Comments
 (0)