forked from extern/alertik
Initial handling for environment events
This commit is contained in:
parent
25bc29f174
commit
17c7f129e3
32
alertik.c
32
alertik.c
@ -5,7 +5,6 @@
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "alertik.h"
|
||||
@ -15,35 +14,32 @@
|
||||
#include "notifiers.h"
|
||||
#include "syslog.h"
|
||||
|
||||
/* Misc. */
|
||||
#define LAST_SENT_THRESHOLD_SECS 10 /* Minimum time (in secs) between two */
|
||||
time_t time_last_sent_notify; /* notifications. */
|
||||
|
||||
/*
|
||||
* Alertik
|
||||
*/
|
||||
|
||||
static void *handle_messages(void *p)
|
||||
{
|
||||
((void)p);
|
||||
size_t i;
|
||||
|
||||
int handled = 0;
|
||||
struct log_event ev = {0};
|
||||
|
||||
while (syslog_pop_msg_from_fifo(&ev) >= 0) {
|
||||
print_log_event(&ev);
|
||||
|
||||
if ((time(NULL) - time_last_sent_notify) <= LAST_SENT_THRESHOLD_SECS) {
|
||||
if (!is_within_notify_threshold()) {
|
||||
log_msg("ignoring, reason: too many notifications!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if it belongs to any of our desired events. */
|
||||
for (i = 0; i < NUM_EVENTS; i++) {
|
||||
if (strstr(ev.msg, handlers[i].str)) {
|
||||
handlers[i].hnd(&ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
handled = process_static_event(&ev);
|
||||
handled += process_environment_event(&ev);
|
||||
|
||||
if (i == NUM_EVENTS)
|
||||
log_msg("> No match!\n");
|
||||
if (handled)
|
||||
update_notify_last_sent();
|
||||
else
|
||||
log_msg("> Not handled!\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -53,6 +49,10 @@ int main(void)
|
||||
pthread_t handler;
|
||||
int fd;
|
||||
|
||||
/* TODO: remove setup_notifiers()..
|
||||
* think about env vars for the static events too, like enable/disable
|
||||
*/
|
||||
|
||||
log_init();
|
||||
setup_notifiers();
|
||||
init_environment_events();
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
extern time_t time_last_sent_notify;
|
||||
extern char *get_formatted_time(time_t time, char *time_str);
|
||||
extern void log_msg(const char *fmt, ...);
|
||||
extern int send_telegram_notification(const char *msg);
|
||||
|
81
env_events.c
81
env_events.c
@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "events.h"
|
||||
#include "env_events.h"
|
||||
#include "alertik.h"
|
||||
#include "notifiers.h"
|
||||
@ -20,6 +21,7 @@
|
||||
static const char *const match_types[] = {"substr", "regex"};
|
||||
|
||||
/* Environment events list. */
|
||||
static int num_env_events;
|
||||
struct env_event env_events[MAX_ENV_EVENTS] = {0};
|
||||
|
||||
/**
|
||||
@ -80,30 +82,89 @@ get_event_idx(int ev_num, char *str, const char *const *str_list, int size)
|
||||
panic("String parameter (%s) invalid for %s\n", env, str);
|
||||
}
|
||||
|
||||
/**/
|
||||
static int handle_regex(struct log_event *ev, int idx_env)
|
||||
{
|
||||
((void)ev);
|
||||
((void)idx_env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int handle_substr(struct log_event *ev, int idx_env)
|
||||
{
|
||||
int notif_idx;
|
||||
char time_str[32] = {0};
|
||||
struct env_event *env_ev;
|
||||
char notification_message[2048] = {0};
|
||||
|
||||
env_ev = &env_events[idx_env];
|
||||
notif_idx = env_ev->ev_notifier_idx;
|
||||
|
||||
if (!strstr(ev->msg, env_ev->ev_match_str))
|
||||
return 0;
|
||||
|
||||
log_msg("> Environment event detected!\n");
|
||||
log_msg("> type: substr, match: (%s), notifier: %s\n",
|
||||
env_ev->ev_match_str, notifiers_str[notif_idx]);
|
||||
|
||||
/* Format the message. */
|
||||
snprintf(
|
||||
notification_message,
|
||||
sizeof notification_message - 1,
|
||||
"%s, at: %s",
|
||||
env_ev->ev_mask_msg,
|
||||
get_formatted_time(ev->timestamp, time_str)
|
||||
);
|
||||
|
||||
if (notifiers[notif_idx].send_notification(notification_message) < 0)
|
||||
log_msg("unable to send the notification through %s\n",
|
||||
notifiers_str[notif_idx]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given an environment-variable event, checks if it
|
||||
* belongs to one of the registered events and then, handle
|
||||
* it.
|
||||
*
|
||||
* @param ev Event to be processed.
|
||||
*
|
||||
* @return Returns the amount of matches, 0 if none (not handled).
|
||||
*/
|
||||
int process_environment_event(struct log_event *ev)
|
||||
{
|
||||
int i;
|
||||
int handled;
|
||||
|
||||
for (i = 0, handled = 0; i < num_env_events; i++) {
|
||||
if (env_events[i].ev_match_type == EVNT_SUBSTR)
|
||||
handled += handle_substr(ev, i);
|
||||
else
|
||||
handled += handle_regex(ev, i);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
int init_environment_events(void)
|
||||
{
|
||||
char *tmp;
|
||||
int events;
|
||||
|
||||
tmp = getenv("ENV_EVENTS");
|
||||
if (!tmp || (str2int(&events, tmp) < 0) || events <= 0) {
|
||||
|
||||
if (!tmp || (str2int(&num_env_events, tmp) < 0) || num_env_events <= 0) {
|
||||
log_msg("Environment events not detected, disabling...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (events >= MAX_ENV_EVENTS)
|
||||
panic("Environment events exceeds the maximum supported (%d/%d)\n",
|
||||
events, MAX_ENV_EVENTS);
|
||||
if (num_env_events >= MAX_ENV_EVENTS)
|
||||
panic("Environment ENV_EVENTS exceeds the maximum supported (%d/%d)\n",
|
||||
num_env_events, MAX_ENV_EVENTS);
|
||||
|
||||
log_msg("%d environment events found, registering...\n");
|
||||
for (int i = 0; i < events; i++) {
|
||||
for (int i = 0; i < num_env_events; i++) {
|
||||
/* EVENTn_MATCH_TYPE. */
|
||||
env_events[i].ev_match_type = get_event_idx(i, "MATCH_TYPE",
|
||||
match_types, MATCH_TYPES_LEN);
|
||||
@ -117,7 +178,7 @@ int init_environment_events(void)
|
||||
}
|
||||
|
||||
log_msg("Environment events summary:\n");
|
||||
for (int i = 0; i < events; i++) {
|
||||
for (int i = 0; i < num_env_events; i++) {
|
||||
printf(
|
||||
"EVENT%d_MATCH_TYPE: %s\n"
|
||||
"EVENT%d_MATCH_STR: %s\n"
|
||||
@ -128,7 +189,9 @@ int init_environment_events(void)
|
||||
i, notifiers_str[env_events[i].ev_notifier_idx],
|
||||
i, env_events[i].ev_mask_msg
|
||||
);
|
||||
}
|
||||
|
||||
/* Try to setup notifier if not yet. */
|
||||
notifiers[env_events[i].ev_notifier_idx].setup();
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define ENV_EVENTS_H
|
||||
|
||||
#define MAX_ENV_EVENTS 16
|
||||
struct log_event;
|
||||
|
||||
struct env_event {
|
||||
int ev_match_type; /* whether regex or str. */
|
||||
@ -17,5 +18,6 @@
|
||||
|
||||
extern struct env_event env_events[MAX_ENV_EVENTS];
|
||||
extern int init_environment_events(void);
|
||||
extern int process_environment_event(struct log_event *ev);
|
||||
|
||||
#endif /* ENV_EVENTS_H */
|
||||
|
23
events.c
23
events.c
@ -21,6 +21,29 @@ struct ev_handler handlers[NUM_EVENTS] = {
|
||||
/* Add new handlers here. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Given an event, checks if it belongs to one of the
|
||||
* registered events and then, handle it.
|
||||
*
|
||||
* @param ev Event to be processed.
|
||||
*
|
||||
* @return Returns the amount of matches, 0 if none (not handled).
|
||||
*/
|
||||
int process_static_event(struct log_event *ev)
|
||||
{
|
||||
int i;
|
||||
int handled;
|
||||
|
||||
for (i = 0, handled = 0; i < NUM_EVENTS; i++) {
|
||||
if (strstr(ev->msg, handlers[i].str)) {
|
||||
handlers[i].hnd(ev);
|
||||
handled += 1;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// FAILED LOGIN ATTEMPTS ///////////////////////////
|
||||
static int
|
||||
parse_login_attempt_msg(const char *msg, char *wifi_iface, char *mac_addr)
|
||||
|
5
events.h
5
events.h
@ -11,8 +11,8 @@
|
||||
#define MSG_MAX 2048
|
||||
#define NUM_EVENTS 1
|
||||
|
||||
#define EVNT_SUBSTR 1
|
||||
#define EVNT_REGEX 2
|
||||
#define EVNT_SUBSTR 0
|
||||
#define EVNT_REGEX 1
|
||||
|
||||
/* Log event. */
|
||||
struct log_event {
|
||||
@ -27,5 +27,6 @@
|
||||
};
|
||||
|
||||
extern struct ev_handler handlers[NUM_EVENTS];
|
||||
extern int process_static_event(struct log_event *ev);
|
||||
|
||||
#endif /* EVENTS_H */
|
||||
|
1
log.h
1
log.h
@ -8,6 +8,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
struct log_event;
|
||||
|
||||
|
25
notifiers.c
25
notifiers.c
@ -12,6 +12,13 @@
|
||||
#include "notifiers.h"
|
||||
#include "alertik.h"
|
||||
|
||||
/*
|
||||
* Notification handling/notifiers
|
||||
*/
|
||||
|
||||
/* EPOCH in secs of last sent notification. */
|
||||
static time_t time_last_sent_notify;
|
||||
|
||||
/* Just to omit the print to stdout. */
|
||||
size_t libcurl_noop_cb(void *ptr, size_t size, size_t nmemb, void *data) {
|
||||
((void)ptr);
|
||||
@ -19,6 +26,16 @@ size_t libcurl_noop_cb(void *ptr, size_t size, size_t nmemb, void *data) {
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/**/
|
||||
void update_notify_last_sent(void) {
|
||||
time_last_sent_notify = time(NULL);
|
||||
}
|
||||
|
||||
/**/
|
||||
int is_within_notify_threshold(void) {
|
||||
return (time(NULL) - time_last_sent_notify) > LAST_SENT_THRESHOLD_SECS;
|
||||
}
|
||||
|
||||
//////////////////////////////// TELEGRAM //////////////////////////////////////
|
||||
/* Telegram & request settings. */
|
||||
static char *telegram_bot_token;
|
||||
@ -26,6 +43,10 @@ static char *telegram_chat_id;
|
||||
|
||||
void setup_telegram(void)
|
||||
{
|
||||
static int setup = 0;
|
||||
if (setup)
|
||||
return;
|
||||
|
||||
telegram_bot_token = getenv("TELEGRAM_BOT_TOKEN");
|
||||
telegram_chat_id = getenv("TELEGRAM_CHAT_ID");
|
||||
if (!telegram_bot_token || !telegram_chat_id) {
|
||||
@ -36,6 +57,7 @@ void setup_telegram(void)
|
||||
"- TELEGRAM_CHAT_ID\n"
|
||||
);
|
||||
}
|
||||
setup = 1;
|
||||
}
|
||||
|
||||
int send_telegram_notification(const char *msg)
|
||||
@ -87,8 +109,7 @@ int send_telegram_notification(const char *msg)
|
||||
log_msg("> Unable to send request!\n");
|
||||
goto error;
|
||||
} else {
|
||||
time_last_sent_notify = time(NULL); /* Update the time of our last sent */
|
||||
log_msg("> Done!\n"); /* notification. */
|
||||
log_msg("> Done!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
#define NUM_NOTIFIERS 1
|
||||
|
||||
/* Minimum time (in secs) between two */
|
||||
#define LAST_SENT_THRESHOLD_SECS 10
|
||||
|
||||
/* Notifiers list, like:
|
||||
* - Telegram
|
||||
* - Slack
|
||||
@ -32,5 +35,7 @@
|
||||
|
||||
extern struct notifier notifiers[NUM_NOTIFIERS];
|
||||
extern void setup_notifiers(void);
|
||||
extern int is_within_notify_threshold(void);
|
||||
extern void update_notify_last_sent(void);
|
||||
|
||||
#endif /* NOTIFIERS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user