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!