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 "fastevent.h"
#include "logging.h"
#include "string_renderer.h"
#include "admin.h"
#include "connection.h"
#include "client.h"
@ -90,6 +91,32 @@ const char * event_extra_key_name(event_extra_key_t key)
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* */
static void event_addref(event_t *event) {
if (!event)

View File

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

View File

@ -12,7 +12,13 @@
#include <string.h>
#include "icecasttypes.h"
#include <igloo/ro.h>
#include <igloo/error.h>
#include "event.h"
#include "global.h" /* for igloo_instance */
#include "string_renderer.h"
#include "util.h"
#include "cfgfile.h"
#include "logging.h"
@ -24,23 +30,24 @@ typedef struct event_log {
int level;
} event_log_t;
static int event_log_emit(void *state, event_t *event) {
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,
"%s%strigger=%# H uri=%#H "
"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",
"%s%s%s",
self->prefix ? self->prefix : "", self->prefix ? ": " : "",
event->trigger,
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,
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)
);
string_renderer_to_string_zero_copy(renderer));
igloo_ro_unref(&renderer);
return 0;
}

View File

@ -12,6 +12,12 @@
#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 "event.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) {
event_url_t *self = state;
ice_config_t *config;
char *action, *mount, *server, *role, *username, *ip, *agent, *media_type;
time_t duration;
char post[4096];
string_renderer_t * renderer;
action = util_url_escape(self->action ? self->action : event->trigger);
mount = __escape(event_extra_get(event, EVENT_EXTRA_KEY_URI), "");
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 (igloo_ro_new(&renderer, string_renderer_t, igloo_instance) != igloo_ERROR_NONE)
return 0;
if (event->connection_time) {
if (event->client_data) {
duration = time(NULL) - event->connection_time;
} else {
duration = 0;
}
config = config_get_config();
server = __escape(config->hostname, "");
string_renderer_start_list_formdata(renderer);
/* 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),
"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",
action, mount, server, config->port,
event->connection_id, role, username, ip, agent, (long long int)duration, event->client_admin_command,
media_type
);
/* new style */
event_to_string_renderer(event, renderer);
/* common */
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();
free(action);
free(mount);
free(server);
free(role);
free(username);
free(ip);
free(agent);
free(media_type);
string_renderer_end_list(renderer);
if (strchr(self->url, '@') == NULL && 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_POSTFIELDS, post);
curl_easy_setopt(self->handle, CURLOPT_POSTFIELDS, string_renderer_to_string_zero_copy(renderer));
if (curl_easy_perform(self->handle))
ICECAST_LOG_WARN("auth to server %s failed with %s", self->url, self->errormsg);
igloo_ro_unref(&renderer);
return 0;
}