feat: 日志增强功能

This commit is contained in:
2026-04-14 20:52:41 +08:00
parent 579e67a3db
commit e895cdc9de
35 changed files with 1324 additions and 21 deletions

View File

@@ -18,7 +18,7 @@ kcp_packet_debug_logger_t *kcp_packet_debug_open_jsonl(const char *path) {
fclose(file);
return NULL;
}
omni_file_logger_init(&logger->file_logger, file);
omni_file_logger_init_path(&logger->file_logger, file, path, 0);
logger->enabled = 1;
return logger;
}

View File

@@ -73,7 +73,7 @@ kcp_session_stats_logger_t *kcp_session_stats_open_jsonl(const char *path) {
fclose(file);
return NULL;
}
omni_file_logger_init(&logger->file_logger, file);
omni_file_logger_init_path(&logger->file_logger, file, path, 0);
logger->enabled = 1;
return logger;
}

View File

@@ -32,7 +32,7 @@ latency_logger_t *latencylog_open_jsonl(const char *path) {
fclose(file);
return NULL;
}
omni_file_logger_init(&logger->file_logger, file);
omni_file_logger_init_path(&logger->file_logger, file, path, 0);
logger->enabled = 1;
return logger;
}

View File

@@ -544,9 +544,217 @@ const char *omni_path_base_name(const char *path) {
return slash == NULL ? path : slash + 1;
}
static uint64_t omni_now_monotonic_ms64(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) ts.tv_sec * 1000ULL + (uint64_t) (ts.tv_nsec / 1000000L);
}
static int omni_positive_int_env(const char *name, int default_value) {
const char *raw = getenv(name);
long parsed;
char *endptr = NULL;
if (raw == NULL || raw[0] == '\0') {
return default_value;
}
parsed = strtol(raw, &endptr, 10);
if (endptr == raw || *endptr != '\0' || parsed <= 0) {
return default_value;
}
return (int) parsed;
}
static size_t omni_positive_size_env(const char *name, size_t default_value) {
const char *raw = getenv(name);
unsigned long long parsed;
char *endptr = NULL;
if (raw == NULL || raw[0] == '\0') {
return default_value;
}
parsed = strtoull(raw, &endptr, 10);
if (endptr == raw || *endptr != '\0' || parsed == 0ULL) {
return default_value;
}
return (size_t) parsed;
}
static int omni_file_logger_flush_locked(omni_file_logger_t *logger, uint64_t now_ms) {
if (logger == NULL || logger->file == NULL) {
errno = EINVAL;
return -1;
}
if (fflush(logger->file) != 0) {
return -1;
}
logger->buffered_bytes = 0U;
logger->last_flush_monotonic_ms = now_ms;
return 0;
}
static int omni_build_rotated_path(char *buffer, size_t buffer_len, const char *path, int suffix) {
size_t path_len;
int written;
if (buffer == NULL || buffer_len == 0U || path == NULL || path[0] == '\0') {
errno = EINVAL;
return -1;
}
path_len = strlen(path);
if (path_len + 16U >= buffer_len) {
errno = ENAMETOOLONG;
return -1;
}
memcpy(buffer, path, path_len);
written = snprintf(buffer + path_len, buffer_len - path_len, ".%d", suffix);
if (written < 0 || (size_t) written >= buffer_len - path_len) {
errno = ENAMETOOLONG;
return -1;
}
return 0;
}
static int omni_file_logger_reopen_append_locked(omni_file_logger_t *logger) {
struct stat st;
FILE *file;
if (logger == NULL || logger->path[0] == '\0') {
errno = EINVAL;
return -1;
}
file = fopen(logger->path, "ab");
if (file == NULL) {
return -1;
}
logger->file = file;
logger->current_bytes = 0U;
if (stat(logger->path, &st) == 0) {
logger->current_bytes = (size_t) st.st_size;
}
logger->buffered_bytes = 0U;
logger->last_flush_monotonic_ms = omni_now_monotonic_ms64();
return 0;
}
static int omni_file_logger_recover_after_rotate_locked(omni_file_logger_t *logger, const char *rotated_current_path) {
int reopen_errno;
if (omni_file_logger_reopen_append_locked(logger) == 0) {
return 0;
}
reopen_errno = errno;
if (rotated_current_path != NULL && rotated_current_path[0] != '\0') {
if (rename(rotated_current_path, logger->path) == 0) {
if (omni_file_logger_reopen_append_locked(logger) == 0) {
return 0;
}
}
}
errno = reopen_errno;
return -1;
}
static int omni_file_logger_rotate_locked(omni_file_logger_t *logger) {
int index;
int saved_errno = 0;
int should_recover = 0;
char rotated_current_path[PATH_MAX];
char from_path[PATH_MAX];
char to_path[PATH_MAX];
if (logger == NULL || logger->path[0] == '\0' || logger->max_bytes == 0U || logger->max_files <= 0) {
return 0;
}
rotated_current_path[0] = '\0';
if (logger->file != NULL) {
if (omni_file_logger_flush_locked(logger, omni_now_monotonic_ms64()) != 0) {
return -1;
}
should_recover = 1;
if (fclose(logger->file) != 0) {
logger->file = NULL;
saved_errno = errno;
goto recover;
}
logger->file = NULL;
}
if (omni_build_rotated_path(from_path, sizeof(from_path), logger->path, logger->max_files) != 0) {
saved_errno = errno;
goto recover;
}
unlink(from_path);
for (index = logger->max_files - 1; index >= 1; --index) {
if (omni_build_rotated_path(from_path, sizeof(from_path), logger->path, index) != 0 ||
omni_build_rotated_path(to_path, sizeof(to_path), logger->path, index + 1) != 0) {
saved_errno = errno;
goto recover;
}
if (rename(from_path, to_path) != 0 && errno != ENOENT) {
saved_errno = errno;
goto recover;
}
}
if (omni_build_rotated_path(to_path, sizeof(to_path), logger->path, 1) != 0) {
saved_errno = errno;
goto recover;
}
if (rename(logger->path, to_path) != 0 && errno != ENOENT) {
saved_errno = errno;
goto recover;
}
snprintf(rotated_current_path, sizeof(rotated_current_path), "%s", to_path);
if (omni_file_logger_reopen_append_locked(logger) != 0) {
saved_errno = errno;
goto recover;
}
return 0;
recover:
if (should_recover) {
int recover_errno = saved_errno != 0 ? saved_errno : errno;
if (omni_file_logger_recover_after_rotate_locked(logger, rotated_current_path) == 0) {
errno = recover_errno;
} else if (saved_errno != 0) {
errno = saved_errno;
}
} else if (saved_errno != 0) {
errno = saved_errno;
}
return -1;
}
void omni_file_logger_init(omni_file_logger_t *logger, FILE *file) {
memset(logger, 0, sizeof(*logger));
logger->file = file;
pthread_mutex_init(&logger->mutex, NULL);
logger->flush_bytes = 1U;
logger->flush_interval_ms = 0;
logger->immediate_flush = 1;
logger->last_flush_monotonic_ms = omni_now_monotonic_ms64();
}
void omni_file_logger_init_path(omni_file_logger_t *logger, FILE *file, const char *path, int immediate_flush) {
struct stat st;
omni_file_logger_init(logger, file);
if (path != NULL && path[0] != '\0') {
snprintf(logger->path, sizeof(logger->path), "%s", path);
if (stat(path, &st) == 0) {
logger->current_bytes = (size_t) st.st_size;
}
}
logger->flush_bytes = omni_positive_size_env("BLITZ_JSONL_FLUSH_BYTES", 262144U);
logger->flush_interval_ms = omni_positive_int_env("BLITZ_JSONL_FLUSH_INTERVAL_MS", 1000);
logger->max_bytes = omni_positive_size_env("BLITZ_JSONL_ROTATE_BYTES", 134217728U);
logger->max_files = omni_positive_int_env("BLITZ_JSONL_ROTATE_FILES", 8);
logger->immediate_flush = immediate_flush != 0;
}
void omni_file_logger_destroy(omni_file_logger_t *logger) {
@@ -555,13 +763,32 @@ void omni_file_logger_destroy(omni_file_logger_t *logger) {
int omni_file_logger_write_line(omni_file_logger_t *logger, const char *line) {
int rc = 0;
size_t line_len;
uint64_t now_ms;
if (logger == NULL || logger->file == NULL || line == NULL) {
errno = EINVAL;
return -1;
}
line_len = strlen(line) + 1U;
now_ms = omni_now_monotonic_ms64();
pthread_mutex_lock(&logger->mutex);
if (fputs(line, logger->file) == EOF || fputc('\n', logger->file) == EOF || fflush(logger->file) != 0) {
if (fputs(line, logger->file) == EOF || fputc('\n', logger->file) == EOF) {
rc = -1;
} else {
logger->current_bytes += line_len;
logger->buffered_bytes += line_len;
if (logger->immediate_flush ||
logger->buffered_bytes >= logger->flush_bytes ||
(logger->flush_interval_ms > 0 && now_ms - logger->last_flush_monotonic_ms >= (uint64_t) logger->flush_interval_ms)) {
if (omni_file_logger_flush_locked(logger, now_ms) != 0) {
rc = -1;
}
}
if (rc == 0 && logger->max_bytes > 0U && logger->current_bytes >= logger->max_bytes) {
if (omni_file_logger_rotate_locked(logger) != 0) {
rc = -1;
}
}
}
pthread_mutex_unlock(&logger->mutex);
return rc;

View File

@@ -18,7 +18,7 @@ tx_timestamp_debug_logger_t *tx_timestamp_debug_open_jsonl(const char *path) {
fclose(file);
return NULL;
}
omni_file_logger_init(&logger->file_logger, file);
omni_file_logger_init_path(&logger->file_logger, file, path, 0);
logger->enabled = 1;
return logger;
}

View File

@@ -213,6 +213,8 @@ void video_pipeline_config_init(video_pipeline_config_t *config) {
config->hard_backpressure_hold_ms = VIDEO_HARD_BACKPRESSURE_HOLD_MS_DEFAULT;
config->server_idle_reconnect_ms = VIDEO_DEFAULT_SERVER_IDLE_RECONNECT_MS;
config->frame_stall_reconnect_ms = VIDEO_DEFAULT_FRAME_STALL_RECONNECT_MS;
config->stats_logger = NULL;
config->stats_interval_ms = 1000;
}
void video_pipeline_config_load_env(video_pipeline_config_t *config) {
@@ -235,6 +237,7 @@ void video_pipeline_config_load_env(video_pipeline_config_t *config) {
config->hard_backpressure_hold_ms = env_int_or_default("OMNI_VIDEO_HARD_BACKPRESSURE_HOLD_MS", config->hard_backpressure_hold_ms);
config->server_idle_reconnect_ms = env_int_or_default("OMNI_VIDEO_SERVER_IDLE_RECONNECT_MS", config->server_idle_reconnect_ms);
config->frame_stall_reconnect_ms = env_int_or_default("OMNI_VIDEO_FRAME_STALL_RECONNECT_MS", config->frame_stall_reconnect_ms);
config->stats_interval_ms = env_int_or_default("BLITZ_KCP_STATS_INTERVAL_MS", config->stats_interval_ms);
}
int video_pipeline_stats_init(video_pipeline_stats_t *stats) {
@@ -600,8 +603,8 @@ static int video_sender_init(video_sender_t *sender, const video_pipeline_config
&options,
NULL,
NULL,
NULL,
KCP_DEFAULT_STATS_INTERVAL_MS
config->stats_logger,
config->stats_interval_ms
);
if (sender->client == NULL) {
return -1;

View File

@@ -186,6 +186,8 @@ void video_pipeline_config_init(video_pipeline_config_t *config) {
config->output_height = VIDEO_OUTPUT_HEIGHT_DEFAULT;
config->max_frames = 0;
config->enable_timing_logs = 0;
config->stats_logger = NULL;
config->stats_interval_ms = 1000;
}
void video_pipeline_config_load_env(video_pipeline_config_t *config) {
@@ -203,6 +205,7 @@ void video_pipeline_config_load_env(video_pipeline_config_t *config) {
config->max_frames = atoi(getenv("OMNI_VIDEO_MAX_FRAMES"));
}
config->enable_timing_logs = env_flag_or_default("OMNI_VIDEO_DEBUG_TIMING", config->enable_timing_logs);
config->stats_interval_ms = env_int_or_default("BLITZ_KCP_STATS_INTERVAL_MS", config->stats_interval_ms);
}
int video_pipeline_stats_init(video_pipeline_stats_t *stats) {
@@ -564,8 +567,8 @@ static int video_sender_init(video_sender_t *sender, const video_pipeline_config
&options,
NULL,
NULL,
NULL,
KCP_DEFAULT_STATS_INTERVAL_MS
config->stats_logger,
config->stats_interval_ms
);
if (sender->client == NULL) {
return -1;