I played a bit with various interaction with outer world ideas in MySQL UDFs and ended up with something what was really really simple – a single libc call. I did shamelessly steal bare bones and simply added a single line of code in it:
#include <mysql.h> #include <string.h> #include <syslog.h> my_bool logger_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { initid->maybe_null=0; return 0; } long long logger(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { if (args->arg_count != 1) { strcpy(error, "LOGGER(): needs message"); return 1; } if (args->arg_type[0] != STRING_RESULT) { strcpy(error, "LOGGER() message should be string"); return 1; } syslog(LOG_INFO,"%s",args->args[0]); *is_null = 0; *error = 0; return 0; }
Of course, I had to compile it:
gcc -I /usr/include/mysql/ -shared -o syslogudf.so syslogudf.c
And later load it:
mysql> create function logger returns integer soname 'syslogudf.so'; Query OK, 0 rows affected (0.00 sec)
One more thing… testing:
mysql> select logger(concat(user()," wishes you ", -> if(rand()>0.3,"good","bad")," luck")); +---------------------------------------------------------------------------+ | logger(concat(user()," wishes you ",if(rand()>0.3,"good","bad")," luck")) | +---------------------------------------------------------------------------+ | 0 | +---------------------------------------------------------------------------+ 1 row in set (0.00 sec)
So now our systems administrator will see:
$ tail -1 /var/log/messages Dec 12 01:09:22 flake mysqld-max: root@localhost wishes you bad luck
Oops!