1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2025-02-02 15:07:36 -05:00

Feature: Added uniform way to include event data in log and URL event backend

This commit is contained in:
Philipp Schafft 2022-09-17 16:53:38 +00:00
parent 7d889b7294
commit 57ba8c2297
4 changed files with 82 additions and 39 deletions

View File

@ -22,6 +22,7 @@
#include "event.h" #include "event.h"
#include "fastevent.h" #include "fastevent.h"
#include "logging.h" #include "logging.h"
#include "string_renderer.h"
#include "admin.h" #include "admin.h"
#include "connection.h" #include "connection.h"
#include "client.h" #include "client.h"
@ -90,6 +91,32 @@ const char * event_extra_key_name(event_extra_key_t key)
return NULL; return NULL;
} }
igloo_error_t event_to_string_renderer(const event_t *event, string_renderer_t *renderer)
{
static const event_extra_key_t key_list[] = {
EVENT_EXTRA_KEY_URI,
EVENT_EXTRA_KEY_SOURCE_MEDIA_TYPE,
EVENT_EXTRA_KEY_CONNECTION_IP,
EVENT_EXTRA_KEY_CLIENT_ROLE,
EVENT_EXTRA_KEY_CLIENT_USERNAME,
EVENT_EXTRA_KEY_CLIENT_USERAGENT,
EVENT_EXTRA_LIST_END
};
string_renderer_add_kv_with_options(renderer, "trigger", event->trigger, STRING_RENDERER_ENCODING_PLAIN, false, false);
for (size_t i = 0; key_list[i] != EVENT_EXTRA_LIST_END; i++) {
string_renderer_add_kv_with_options(renderer, event_extra_key_name(key_list[i]), event_extra_get(event, key_list[i]), STRING_RENDERER_ENCODING_PLAIN, false, false);
}
if (event->client_data) {
string_renderer_add_ki_with_options(renderer, "connection-id", event->connection_id, STRING_RENDERER_ENCODING_PLAIN, true, false);
string_renderer_add_ki_with_options(renderer, "connection-time", event->connection_time, STRING_RENDERER_ENCODING_PLAIN, true, false);
string_renderer_add_ki_with_options(renderer, "client-admin-command", event->client_admin_command, STRING_RENDERER_ENCODING_PLAIN, true, false);
}
return igloo_ERROR_NONE;
}
/* work with event_t* */ /* work with event_t* */
static void event_addref(event_t *event) { static void event_addref(event_t *event) {
if (!event) if (!event)

View File

@ -15,6 +15,8 @@
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/tree.h> #include <libxml/tree.h>
#include <igloo/error.h>
#include "common/thread/thread.h" #include "common/thread/thread.h"
#include "icecasttypes.h" #include "icecasttypes.h"
@ -125,6 +127,7 @@ void event_emit_va(const char *trigger, ...);
/* reading extra from events */ /* reading extra from events */
const char * event_extra_get(const event_t *event, const event_extra_key_t key); const char * event_extra_get(const event_t *event, const event_extra_key_t key);
const char * event_extra_key_name(event_extra_key_t key); const char * event_extra_key_name(event_extra_key_t key);
igloo_error_t event_to_string_renderer(const event_t *event, string_renderer_t *renderer); /* expects renderer in list mode */
/* Implementations */ /* Implementations */
int event_get_exec(event_registration_t *er, config_options_t *options); int event_get_exec(event_registration_t *er, config_options_t *options);

View File

@ -12,7 +12,13 @@
#include <string.h> #include <string.h>
#include "icecasttypes.h"
#include <igloo/ro.h>
#include <igloo/error.h>
#include "event.h" #include "event.h"
#include "global.h" /* for igloo_instance */
#include "string_renderer.h"
#include "util.h" #include "util.h"
#include "cfgfile.h" #include "cfgfile.h"
#include "logging.h" #include "logging.h"
@ -24,23 +30,24 @@ typedef struct event_log {
int level; int level;
} event_log_t; } event_log_t;
static int event_log_emit(void *state, event_t *event) { static int event_log_emit(void *state, event_t *event) {
event_log_t *self = state; event_log_t *self = state;
string_renderer_t * renderer;
if (igloo_ro_new(&renderer, string_renderer_t, igloo_instance) != igloo_ERROR_NONE)
return 0;
string_renderer_start_list(renderer, " ", "=", false, false, STRING_RENDERER_ENCODING_H_ALT_SPACE);
event_to_string_renderer(event, renderer);
string_renderer_end_list(renderer);
ICECAST_LOG(self->level, ICECAST_LOGFLAG_NONE, ICECAST_LOG(self->level, ICECAST_LOGFLAG_NONE,
"%s%strigger=%# H uri=%#H " "%s%s%s",
"connection_id=%lu connection_ip=%#H connection_time=%lli "
"client_role=%# H client_username=%#H client_useragent=%# H client_admin_command=%i source_media_type=%#H",
self->prefix ? self->prefix : "", self->prefix ? ": " : "", self->prefix ? self->prefix : "", self->prefix ? ": " : "",
event->trigger, string_renderer_to_string_zero_copy(renderer));
event_extra_get(event, EVENT_EXTRA_KEY_URI),
event->connection_id, event_extra_get(event, EVENT_EXTRA_KEY_CONNECTION_IP), (long long int)event->connection_time, igloo_ro_unref(&renderer);
event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_ROLE),
event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERNAME),
event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERAGENT),
event->client_admin_command,
event_extra_get(event, EVENT_EXTRA_KEY_SOURCE_MEDIA_TYPE)
);
return 0; return 0;
} }

View File

@ -12,6 +12,12 @@
#include <string.h> #include <string.h>
#include "icecasttypes.h"
#include <igloo/ro.h>
#include <igloo/error.h>
#include "global.h" /* for igloo_instance */
#include "string_renderer.h"
#include "curl.h" #include "curl.h"
#include "event.h" #include "event.h"
#include "cfgfile.h" #include "cfgfile.h"
@ -43,43 +49,41 @@ static inline char *__escape(const char *src, const char *default_value) {
static int event_url_emit(void *state, event_t *event) { static int event_url_emit(void *state, event_t *event) {
event_url_t *self = state; event_url_t *self = state;
ice_config_t *config; ice_config_t *config;
char *action, *mount, *server, *role, *username, *ip, *agent, *media_type;
time_t duration; time_t duration;
char post[4096]; string_renderer_t * renderer;
action = util_url_escape(self->action ? self->action : event->trigger); if (igloo_ro_new(&renderer, string_renderer_t, igloo_instance) != igloo_ERROR_NONE)
mount = __escape(event_extra_get(event, EVENT_EXTRA_KEY_URI), ""); return 0;
role = __escape(event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_ROLE), "");
username = __escape(event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERNAME), "");
ip = __escape(event_extra_get(event, EVENT_EXTRA_KEY_CONNECTION_IP), "");
agent = __escape(event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERAGENT), "-");
media_type = __escape(event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERAGENT), "-");
if (event->connection_time) { if (event->client_data) {
duration = time(NULL) - event->connection_time; duration = time(NULL) - event->connection_time;
} else { } else {
duration = 0; duration = 0;
} }
config = config_get_config(); string_renderer_start_list_formdata(renderer);
server = __escape(config->hostname, ""); /* Old style */
string_renderer_add_kv_with_options(renderer, "action", self->action ? self->action : event->trigger, STRING_RENDERER_ENCODING_PLAIN, false, false);
string_renderer_add_kv_with_options(renderer, "mount", event_extra_get(event, EVENT_EXTRA_KEY_URI), STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_ki_with_options(renderer, "client", event->connection_id, STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_kv_with_options(renderer, "role", event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_ROLE), STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_kv_with_options(renderer, "username", event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERNAME), STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_kv_with_options(renderer, "ip", event_extra_get(event, EVENT_EXTRA_KEY_CONNECTION_IP), STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_kv_with_options(renderer, "agent", event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERAGENT) ? event_extra_get(event, EVENT_EXTRA_KEY_CLIENT_USERAGENT) : "-", STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_ki_with_options(renderer, "duration", duration, STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_ki_with_options(renderer, "admin", event->client_admin_command, STRING_RENDERER_ENCODING_PLAIN, true, true);
snprintf (post, sizeof (post), /* new style */
"action=%s&mount=%s&server=%s&port=%d&client=%lu&role=%s&username=%s&ip=%s&agent=%s&duration=%lli&admin=%i&source-media-type=%s", event_to_string_renderer(event, renderer);
action, mount, server, config->port,
event->connection_id, role, username, ip, agent, (long long int)duration, event->client_admin_command, /* common */
media_type config = config_get_config();
); string_renderer_add_kv_with_options(renderer, "server", config->hostname, STRING_RENDERER_ENCODING_PLAIN, true, true);
string_renderer_add_ki_with_options(renderer, "port", config->port, STRING_RENDERER_ENCODING_PLAIN, true, true);
config_release_config(); config_release_config();
free(action); string_renderer_end_list(renderer);
free(mount);
free(server);
free(role);
free(username);
free(ip);
free(agent);
free(media_type);
if (strchr(self->url, '@') == NULL && self->userpwd) { if (strchr(self->url, '@') == NULL && self->userpwd) {
curl_easy_setopt(self->handle, CURLOPT_USERPWD, self->userpwd); curl_easy_setopt(self->handle, CURLOPT_USERPWD, self->userpwd);
@ -88,11 +92,13 @@ static int event_url_emit(void *state, event_t *event) {
} }
curl_easy_setopt(self->handle, CURLOPT_URL, self->url); curl_easy_setopt(self->handle, CURLOPT_URL, self->url);
curl_easy_setopt(self->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt(self->handle, CURLOPT_POSTFIELDS, string_renderer_to_string_zero_copy(renderer));
if (curl_easy_perform(self->handle)) if (curl_easy_perform(self->handle))
ICECAST_LOG_WARN("auth to server %s failed with %s", self->url, self->errormsg); ICECAST_LOG_WARN("auth to server %s failed with %s", self->url, self->errormsg);
igloo_ro_unref(&renderer);
return 0; return 0;
} }