#include "precompile.h" #include "log_udpclient.h" #include "log_hdr.h" #include "log_base.h" #include "log.h" #include "spinlock.h" #include #include typedef struct udplogfactory_t udplogfactory_t; typedef struct udplog_t { logbase_t base; char *sink_inst; char *ip; unsigned short port; struct sockaddr_in sink_addr; }udplog_t; struct udplogfactory_t { logfactory_t base; lock_t lock; SOCKET sock_handle; }; static void udplogfactory_destroy(void *self) { udplogfactory_t *fac = (udplogfactory_t *)self; if (fac) { if (fac->sock_handle != INVALID_SOCKET) { closesocket(fac->sock_handle); fac->sock_handle = INVALID_SOCKET; } if (fac->base.name) { free(fac->base.name); fac->base.name = NULL; } free(fac); } } static void* udplogfactory_create_log(void *self, const char* inst) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *log = MALLOC_T(udplog_t); log->base.level = XLOG_LEVEL_ALL; log->base.factory = self; log->base.inst_name = _strdup(inst); log->sink_inst = _strdup(log->base.inst_name); log->ip = 0; log->port = 0; if (fac->sock_handle == INVALID_SOCKET) { fac->sock_handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); } return log; } static int udplogfactory_set_log_param(void *self, void *log, const char *key, const char *value) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *slog = (udplog_t*)log; if (_stricmp(key, "ip") == 0) { slog->ip = _strdup(value); } else if (_stricmp(key, "port") == 0) { int nport = atoi(value); if (nport <= 65535 && nport > 0) slog->port = (unsigned short)nport; } else if (_stricmp(key, "inst") == 0) { if (slog->sink_inst) free(slog->sink_inst); slog->sink_inst = _strdup(value); } else if (_stricmp(key, "level") == 0) { if (_stricmp(value, "all") == 0) { slog->base.level = 0; } else if (_stricmp(value, "trace") == 0) { slog->base.level = 1; } else if (_stricmp(value, "debug") == 0) { slog->base.level = 2; } else if (_stricmp(value, "info") == 0) { slog->base.level = 3; } else if (_stricmp(value, "warn") == 0) { slog->base.level = 4; } else if (_stricmp(value, "error") == 0) { slog->base.level = 5; } else if (_stricmp(value, "fatal") == 0) { slog->base.level = 6; } else if (_stricmp(value, "none") == 0) { slog->base.level = 7; } else { return -1; } } else { return -1; } return 0; } static int udplogfactory_init_log(void *self, void *log) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *slog = (udplog_t*)log; if (!slog->ip || !slog->port) return -1; memset(&slog->sink_addr, 0, sizeof(slog->sink_addr)); slog->sink_addr.sin_family = AF_INET; slog->sink_addr.sin_addr.s_addr = inet_addr(slog->ip); slog->sink_addr.sin_port = htons(slog->port); return 0; } static int udplogfactory_term_log(void *self, void *log) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *slog = (udplog_t*)log; if (slog->sink_inst) { free(slog->sink_inst); slog->sink_inst = NULL; } if (slog->ip) { free(slog->ip); slog->ip = NULL; } return 0; } static void udplogfactory_destroy_log(void *self, void *log) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *slog = (udplog_t*)log; if (slog) { if (slog->base.inst_name) free(slog->base.inst_name); if (slog->sink_inst) free(slog->sink_inst); free(slog); } } static int udplogfactory_record_log(void *self, void *log, int level, unsigned long ts_low, unsigned long ts_high, const char *s, int sn) { udplogfactory_t *fac = (udplogfactory_t *)self; udplog_t *slog = (udplog_t*)log; if (fac->sock_handle) { char tmp[1056]; int n = 0; struct log_hdr *hdr; struct log_hdr_str *logstr; hdr = (struct log_hdr*)&tmp[0]; hdr->level = (unsigned char)level; hdr->reserved = 0; hdr->tag = 'GOLX'; hdr->tick_low = htonl(ts_low); hdr->tick_high = htonl(ts_high); hdr->version = 1; n += sizeof(struct log_hdr); logstr = (struct log_hdr_str *)(&tmp[n]); logstr->len = strlen(slog->sink_inst); memcpy(&logstr->data[0], slog->sink_inst, logstr->len); n += 2 + logstr->len; logstr->len = htons(logstr->len); logstr = (struct log_hdr_str *)(&tmp[n]); logstr->len = sn; memcpy(&logstr->data[0], s, logstr->len); n += 2 + logstr->len; logstr->len = htons(logstr->len); fastlock_enter(fac->lock); sendto(fac->sock_handle, tmp, n, 0, (struct sockaddr*)&slog->sink_addr, sizeof(slog->sink_addr)); fastlock_leave(fac->lock); } return 0; } int udplogfactory_create(logfactory_t **p_fac) { udplogfactory_t *fac; if (!p_fac) return -1; fac = MALLOC_T(udplogfactory_t); fac->sock_handle = INVALID_SOCKET; fac->base.name = _strdup("udpclient"); fac->base.record_log = &udplogfactory_record_log; fac->base.init_log = &udplogfactory_init_log; fac->base.set_log_param = &udplogfactory_set_log_param; fac->base.term_log = &udplogfactory_term_log; fac->base.create_log = &udplogfactory_create_log; fac->base.destroy_log = &udplogfactory_destroy_log; fac->base.destroy = &udplogfactory_destroy; fastlock_init(fac->lock); *p_fac = &fac->base; return 0; }