feat: 日志增强功能
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "control_protocol.h"
|
||||
#include "latencylog.h"
|
||||
#include "protocol.h"
|
||||
#include "video_pipeline.h"
|
||||
|
||||
@@ -26,6 +27,8 @@
|
||||
#define DEFAULT_VIDEO_THREAD_FAULT_FILE "fault-injection-bside-video-thread-stall"
|
||||
#define DEFAULT_CONTROL_THREAD_FAULT_FILE "fault-injection-bside-control-thread-stall"
|
||||
#define DEFAULT_THREAD_HEARTBEAT_TIMEOUT_SEC 15
|
||||
#define DEFAULT_KCP_STATS_INTERVAL_MS 1000
|
||||
#define DEFAULT_CONTROL_LATENCY_SAMPLE_MOD 100
|
||||
#define EXIT_CODE_VIDEO_THREAD_STALLED 101
|
||||
#define EXIT_CODE_CONTROL_THREAD_STALLED 102
|
||||
|
||||
@@ -65,11 +68,15 @@ typedef struct daemon_state {
|
||||
int control_server_idle_reconnect_ms;
|
||||
const char *runtime_dir;
|
||||
int heartbeat_timeout_sec;
|
||||
int stats_interval_ms;
|
||||
uint64_t control_latency_sample_mod;
|
||||
char status_file_path[512];
|
||||
char video_thread_fault_file[512];
|
||||
char control_thread_fault_file[512];
|
||||
atomic_long video_thread_heartbeat_epoch_sec;
|
||||
atomic_long control_thread_heartbeat_epoch_sec;
|
||||
kcp_session_stats_logger_t *stats_logger;
|
||||
latency_logger_t *control_latency_logger;
|
||||
unix_dgram_client_t unix_client;
|
||||
control_bridge_stats_t control_stats;
|
||||
} daemon_state_t;
|
||||
@@ -127,6 +134,21 @@ static int env_int_or_default(const char *name, int fallback) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
static uint64_t env_u64_or_default(const char *name, uint64_t fallback) {
|
||||
const char *value = getenv(name);
|
||||
unsigned long long parsed = 0ULL;
|
||||
char *endptr = NULL;
|
||||
|
||||
if (value == NULL || value[0] == '\0') {
|
||||
return fallback;
|
||||
}
|
||||
parsed = strtoull(value, &endptr, 10);
|
||||
if (endptr == value || *endptr != '\0' || parsed == 0ULL) {
|
||||
return fallback;
|
||||
}
|
||||
return (uint64_t) parsed;
|
||||
}
|
||||
|
||||
static int64_t realtime_epoch_ms(void) {
|
||||
struct timespec ts;
|
||||
|
||||
@@ -145,6 +167,19 @@ static void update_thread_heartbeat(atomic_long *heartbeat) {
|
||||
atomic_store(heartbeat, realtime_epoch_sec());
|
||||
}
|
||||
|
||||
static int should_log_control_latency(const daemon_state_t *state, const message_t *msg) {
|
||||
uint64_t sample_mod;
|
||||
|
||||
if (state == NULL || state->control_latency_logger == NULL || msg == NULL) {
|
||||
return 0;
|
||||
}
|
||||
sample_mod = state->control_latency_sample_mod;
|
||||
if (sample_mod <= 1U) {
|
||||
return 1;
|
||||
}
|
||||
return msg->id % sample_mod == 0U;
|
||||
}
|
||||
|
||||
static void video_pipeline_heartbeat_progress(void *context) {
|
||||
update_thread_heartbeat((atomic_long *) context);
|
||||
}
|
||||
@@ -556,8 +591,8 @@ static void *control_thread_main(void *arg) {
|
||||
&options,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
KCP_DEFAULT_STATS_INTERVAL_MS
|
||||
state->stats_logger,
|
||||
state->stats_interval_ms
|
||||
);
|
||||
if (client == NULL) {
|
||||
control_bridge_set_errno_error(&state->control_stats, "failed to connect control session");
|
||||
@@ -692,6 +727,11 @@ static void *control_thread_main(void *arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (should_log_control_latency(state, &msg)) {
|
||||
latencylog_log_message_event(state->control_latency_logger, OMNI_NODE_ROLE_PEER, state->control_peer_id, EVENT_B_APP_RECV, &msg);
|
||||
latencylog_log_message_event(state->control_latency_logger, OMNI_NODE_ROLE_PEER, state->control_peer_id, EVENT_B_PERSIST_BEGIN, &msg);
|
||||
}
|
||||
|
||||
if (unix_dgram_client_send(&state->unix_client, msg.body, msg.body_len) != 0) {
|
||||
int send_errno = errno;
|
||||
int recovered = 0;
|
||||
@@ -708,6 +748,9 @@ static void *control_thread_main(void *arg) {
|
||||
state->control_stats.server_idle_ms = client_state.server_idle_ms;
|
||||
kcp_client_runtime_stats_snapshot(client, &state->control_stats.transport);
|
||||
pthread_mutex_unlock(&state->control_stats.mutex);
|
||||
if (should_log_control_latency(state, &msg)) {
|
||||
latencylog_log_message_event(state->control_latency_logger, OMNI_NODE_ROLE_PEER, state->control_peer_id, EVENT_B_PERSIST_END, &msg);
|
||||
}
|
||||
protocol_message_clear(&msg);
|
||||
continue;
|
||||
}
|
||||
@@ -728,6 +771,9 @@ static void *control_thread_main(void *arg) {
|
||||
state->control_stats.server_idle_ms = client_state.server_idle_ms;
|
||||
kcp_client_runtime_stats_snapshot(client, &state->control_stats.transport);
|
||||
pthread_mutex_unlock(&state->control_stats.mutex);
|
||||
if (should_log_control_latency(state, &msg)) {
|
||||
latencylog_log_message_event(state->control_latency_logger, OMNI_NODE_ROLE_PEER, state->control_peer_id, EVENT_B_PERSIST_END, &msg);
|
||||
}
|
||||
protocol_message_clear(&msg);
|
||||
}
|
||||
|
||||
@@ -799,8 +845,12 @@ int main(void) {
|
||||
"BLITZ_OMNID_THREAD_HEARTBEAT_TIMEOUT_SEC",
|
||||
DEFAULT_THREAD_HEARTBEAT_TIMEOUT_SEC
|
||||
);
|
||||
state.stats_interval_ms = env_int_or_default("BLITZ_KCP_STATS_INTERVAL_MS", DEFAULT_KCP_STATS_INTERVAL_MS);
|
||||
state.control_latency_sample_mod = env_u64_or_default("BLITZ_CONTROL_LATENCY_LOG_SAMPLE_MOD", DEFAULT_CONTROL_LATENCY_SAMPLE_MOD);
|
||||
state.video_config.progress_callback = video_pipeline_heartbeat_progress;
|
||||
state.video_config.progress_context = &state.video_thread_heartbeat_epoch_sec;
|
||||
state.video_config.stats_logger = NULL;
|
||||
state.video_config.stats_interval_ms = state.stats_interval_ms;
|
||||
state.control_server_idle_reconnect_ms = env_int_or_default(
|
||||
"OMNI_CONTROL_SERVER_IDLE_RECONNECT_MS",
|
||||
CONTROL_DEFAULT_SERVER_IDLE_RECONNECT_MS
|
||||
@@ -860,11 +910,34 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
const char *stats_log_path = getenv("BLITZ_KCP_STATS_LOG_PATH");
|
||||
const char *latency_log_path = getenv("BLITZ_CONTROL_LATENCY_LOG_PATH");
|
||||
int latency_enabled = env_int_or_default("BLITZ_CONTROL_LATENCY_LOG_ENABLED", 1);
|
||||
|
||||
if (stats_log_path != NULL && stats_log_path[0] != '\0') {
|
||||
state.stats_logger = kcp_session_stats_open_jsonl(stats_log_path);
|
||||
if (state.stats_logger == NULL) {
|
||||
fprintf(stderr, "[b_side_omnid] warning: failed to open KCP stats log %s\n", stats_log_path);
|
||||
}
|
||||
}
|
||||
if (latency_enabled && latency_log_path != NULL && latency_log_path[0] != '\0') {
|
||||
state.control_latency_logger = latencylog_open_jsonl(latency_log_path);
|
||||
if (state.control_latency_logger == NULL) {
|
||||
fprintf(stderr, "[b_side_omnid] warning: failed to open control latency log %s\n", latency_log_path);
|
||||
}
|
||||
}
|
||||
state.video_config.stats_logger = state.stats_logger;
|
||||
state.video_config.stats_interval_ms = state.stats_interval_ms;
|
||||
}
|
||||
|
||||
if (pthread_create(&video_thread, NULL, video_thread_main, &state) != 0) {
|
||||
perror("pthread_create(video_thread)");
|
||||
unix_dgram_client_close(&state.unix_client);
|
||||
control_bridge_stats_destroy(&state.control_stats);
|
||||
video_pipeline_stats_destroy(&state.video_stats);
|
||||
latencylog_close(state.control_latency_logger);
|
||||
kcp_session_stats_close(state.stats_logger);
|
||||
return 1;
|
||||
}
|
||||
if (pthread_create(&control_thread, NULL, control_thread_main, &state) != 0) {
|
||||
@@ -874,6 +947,8 @@ int main(void) {
|
||||
unix_dgram_client_close(&state.unix_client);
|
||||
control_bridge_stats_destroy(&state.control_stats);
|
||||
video_pipeline_stats_destroy(&state.video_stats);
|
||||
latencylog_close(state.control_latency_logger);
|
||||
kcp_session_stats_close(state.stats_logger);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -891,5 +966,7 @@ int main(void) {
|
||||
unix_dgram_client_close(&state.unix_client);
|
||||
control_bridge_stats_destroy(&state.control_stats);
|
||||
video_pipeline_stats_destroy(&state.video_stats);
|
||||
latencylog_close(state.control_latency_logger);
|
||||
kcp_session_stats_close(state.stats_logger);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user