WL#6788: MySQL client: Log interactive commands to syslog

Affects: Server-5.7   —   Status: Complete

Some users need to log all interactive commands entered at MySQL prompt
to syslog. This task would introduce a new client option --syslog to
enable/disable the logging of attributes like sudo_user (or user), mysql_user,
connection_id, db_server, DB, and query entered in an interactive session.

*** Additions & modifications in MySQL command line tool ***

== Log attributes ==
Following attributes will be logged into the syslog
for every command executed in an interactive session:

(a) ENV("SUDO_USER")/ENV("USER")
(b) MySQL User
(c) Connection ID
(d) Server Host
(e) Current DB
(f) Query

However, if the query happens to be a "password_
_carrying_statement", it will get filtered out and
not be logged into syslog. A "password_carrying_
statement" as of now, is marked by the presence of
PASSWORD and/or IDENTIFIED (case insensitive) words
in the given statement.


== Command line option ==
A new command line option 'syslog' to enable/disable
syslog logging will be introduced. It will be disabled
by default.


== Log Filtering ==
In order to perform the filtering of "password_carrying_
statements", the mechanism introduced by BUG#48287 would
be used :

(a) histignore option:
    This option would affect the filtering of both syslog as
    well as mysql history log. It accepts a colon separated
    list of do-not-log patterns.

(b) MYSQL_HISTIGNORE environment variable:
    An alternative to the 'histignore' options. An environment
    variable to hold the do-not-log patterns.


*** New syslog APIs under mysys library ***

Multiple syslog functions (APIs) will be introduced
under mysys library (mysys/my_syslog.c). These function
will use *NIX's syslog() API or Windows event logging
facility based on the platform.

== Logging Levels ==

The new syslog facility will reuse the logging levels
which are already defined under my_global.h.

1) ERROR_LEVER
2) WARNING_LEVEL
3) INFORMATION_LEVEL

include/my_global.h
-------------------
enum loglevel {
   ERROR_LEVEL=       0,
   WARNING_LEVEL=     1,
   INFORMATION_LEVEL= 2
};

These levels will internally be mapped to syslog & Windows'
event reporting system.

--------------------------------------------------------------
|   Logging level   |    *NIX     |         Windows          |
--------------------------------------------------------------
|    ERROR_LEVEL    |   LOG_ERR   |    EVENTLOG_ERROR_TYPE   |
|   WARNING_LEVEL   | LOG_WARNING |   EVENTLOG_WARNING_TYPE  |
| INFORMATION_LEVEL |   LOG_INFO  | EVENTLOG_INFORMATION_TYPE|
--------------------------------------------------------------

== Maximum syslog message size ==

Max syslog message size: #define MAX_SYSLOG_MESSAGE_SIZE 1024
*** New syslog APIs ***

1) int my_syslog(const CHARSET_INFO *cs __attribute__((unused)),
              enum loglevel level,
              const char *msg)

   * On *NIX platforms
     - The incoming message is not converted.
     - Calls syslog() with approptiate log level and the message.

   * On WIndows
     - The incoming message is converted to UCS2 (my_charset_utf16le_bin).
     - A limited buffer of size (MAX_SYSLOG_MESSAGE_SIZE * sizeof(whar_t))
       bytes is allocated to store the converted message.
     - Call ReportEvent() with appropriate log level and the message.

Note: mysql client populates the message in a buffer of size
      MAX_SYSLOG_MESSAGE_SIZE (1K) bytes. Anything beyond this size
      would be truncated.

2) int my_openlog(const char *eventSourceName __attribute__((unused)))
   * On *NIX platforms
     - Calls openlog()
     - Arguments : ident    = eventSourceName
                   option   = LOG_NDELAY (Open the connection immediately)
                   facility = LOG_USER

   * On WIndows
     - Registers the eventsSource :
       hEventLog= RegisterEventSource(NULL, eventSourceName);


3) int my_closelog(void)
   * On *NIX platforms
     - Calls closelog()

   * On WIndows
     - Deregisters the eventsSource : DeregisterEventSource(hEventLog)