mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
5.5 merge and fixes for compiler/test errors
This commit is contained in:
@@ -13,4 +13,4 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
MYSQL_ADD_PLUGIN(sql_errlog sql_errlog.c sql_logger.cc service_logger.h MODULE_ONLY)
|
||||
MYSQL_ADD_PLUGIN(sql_errlog sql_errlog.c MODULE_ONLY)
|
||||
|
@@ -1,21 +0,0 @@
|
||||
/* Copyright (C) 2012 Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <service_versions.h>
|
||||
|
||||
|
||||
/* file reserved for the future use */
|
||||
SERVICE_VERSION *logger_service= (void *) VERSION_logger;
|
||||
|
@@ -1,100 +0,0 @@
|
||||
/* Copyright (C) 2012 Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef MYSQL_SERVICE_LOGGER_INCLUDED
|
||||
#define MYSQL_SERVICE_LOGGER_INCLUDED
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
@file
|
||||
logger service
|
||||
|
||||
Log file with rotation implementation.
|
||||
|
||||
This service implements logging with possible rotation
|
||||
of the log files. Interface intentionally tries to be similar to FILE*
|
||||
related functions.
|
||||
|
||||
So that one can open the log with logger_open(), specifying
|
||||
the limit on the logfile size and the rotations number.
|
||||
|
||||
Then it's possible to write messages to the log with
|
||||
logger_printf or logger_vprintf functions.
|
||||
|
||||
As the size of the logfile grows over the specified limit,
|
||||
it is renamed to 'logfile.1'. The former 'logfile.1' becomes
|
||||
'logfile.2', etc. The file 'logfile.rotations' is removed.
|
||||
That's how the rotation works.
|
||||
|
||||
The rotation can be forced with the logger_rotate() call.
|
||||
|
||||
Finally the log should be closed with logger_close().
|
||||
|
||||
@notes:
|
||||
Implementation checks the size of the log file before it starts new
|
||||
printf into it. So the size of the file gets over the limit when it rotates.
|
||||
|
||||
The access is secured with the mutex, so the log is threadsafe.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct logger_handle_st LOGGER_HANDLE;
|
||||
|
||||
extern struct logger_service_st {
|
||||
LOGGER_HANDLE* (*open)(const char *path,
|
||||
unsigned long long size_limit,
|
||||
unsigned int rotations);
|
||||
int (*close)(LOGGER_HANDLE *log);
|
||||
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
|
||||
int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
|
||||
int (*rotate)(LOGGER_HANDLE *log);
|
||||
} *logger_service;
|
||||
|
||||
#if 0 /*MYSQL_DYNAMIC_PLUGIN*/
|
||||
|
||||
#define logger_open(path, size_limit, rotations) \
|
||||
(logger_service->open(path, size_limit, rotations))
|
||||
#define logger_close(log) (logger_service->close(log))
|
||||
#define logger_rotate(log) (logger_service->rotate(log))
|
||||
#define logger_vprintf(log, fmt, argptr) (logger_service->\
|
||||
vprintf(log, fmt, argptr))
|
||||
#define logger_printf logger_service->printf
|
||||
#else
|
||||
|
||||
LOGGER_HANDLE *logger_open(const char *path,
|
||||
unsigned long long size_limit,
|
||||
unsigned int rotations);
|
||||
int logger_close(LOGGER_HANDLE *log);
|
||||
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
|
||||
int logger_rotate(LOGGER_HANDLE *log);
|
||||
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
|
||||
|
||||
void init_logger_mutexes();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*MYSQL_SERVICE_LOGGER_INCLUDED*/
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#include <mysql/plugin_audit.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "service_logger.h"
|
||||
#include <mysql/service_logger.h>
|
||||
|
||||
/*
|
||||
Disable __attribute__() on non-gcc compilers.
|
||||
@@ -106,7 +106,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)),
|
||||
|
||||
static int sql_error_log_init(void *p __attribute__((unused)))
|
||||
{
|
||||
init_logger_mutexes();
|
||||
logger_init_mutexes();
|
||||
|
||||
logfile= logger_open(filename, size_limit, rotations);
|
||||
if (logfile == NULL) {
|
||||
|
@@ -1,198 +0,0 @@
|
||||
/* Copyright (C) 2012 Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#include "my_global.h"
|
||||
#include <my_sys.h>
|
||||
#include "service_logger.h"
|
||||
#include <my_pthread.h>
|
||||
|
||||
extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
/* These belong to the service initialization */
|
||||
static PSI_mutex_key key_LOCK_logger_service;
|
||||
static PSI_mutex_info mutex_list[]=
|
||||
{{ &key_LOCK_logger_service, "logger_service_file_st::lock", PSI_FLAG_GLOBAL}};
|
||||
#endif
|
||||
|
||||
typedef struct logger_handle_st {
|
||||
File file;
|
||||
char path[FN_REFLEN];
|
||||
unsigned long long size_limit;
|
||||
unsigned int rotations;
|
||||
size_t path_len;
|
||||
mysql_mutex_t lock;
|
||||
} LSFS;
|
||||
|
||||
|
||||
#define LOG_FLAGS (O_APPEND | O_CREAT | O_WRONLY)
|
||||
|
||||
static unsigned int n_dig(unsigned int i)
|
||||
{
|
||||
return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3));
|
||||
}
|
||||
|
||||
|
||||
LOGGER_HANDLE *logger_open(const char *path,
|
||||
unsigned long long size_limit,
|
||||
unsigned int rotations)
|
||||
{
|
||||
LOGGER_HANDLE new_log, *l_perm;
|
||||
|
||||
/*
|
||||
I don't think we ever need more rotations,
|
||||
but if it's so, the rotation procedure should be adapted to it.
|
||||
*/
|
||||
if (rotations > 999)
|
||||
return 0;
|
||||
|
||||
new_log.rotations= rotations;
|
||||
new_log.size_limit= size_limit;
|
||||
new_log.path_len= strlen(fn_format(new_log.path, path,
|
||||
mysql_data_home, "", MY_UNPACK_FILENAME));
|
||||
|
||||
if (new_log.path_len+n_dig(rotations)+1 > FN_REFLEN)
|
||||
{
|
||||
errno= ENAMETOOLONG;
|
||||
/* File path too long */
|
||||
return 0;
|
||||
}
|
||||
if ((new_log.file= my_open(new_log.path, LOG_FLAGS, MYF(0))) < 0)
|
||||
{
|
||||
errno= my_errno;
|
||||
/* Check errno for the cause */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(l_perm= (LOGGER_HANDLE *) my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))
|
||||
{
|
||||
my_close(new_log.file, MYF(0));
|
||||
new_log.file= -1;
|
||||
return 0; /* End of memory */
|
||||
}
|
||||
*l_perm= new_log;
|
||||
mysql_mutex_init(key_LOCK_logger_service, &l_perm->lock, MY_MUTEX_INIT_FAST);
|
||||
return l_perm;
|
||||
}
|
||||
|
||||
int logger_close(LOGGER_HANDLE *log)
|
||||
{
|
||||
int result;
|
||||
File file= log->file;
|
||||
mysql_mutex_destroy(&log->lock);
|
||||
my_free(log);
|
||||
if ((result= my_close(file, MYF(0))))
|
||||
errno= my_errno;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static char *logname(LOGGER_HANDLE *log, char *buf, unsigned int n_log)
|
||||
{
|
||||
sprintf(buf+log->path_len, ".%0*u", n_dig(log->rotations), n_log);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static int do_rotate(LOGGER_HANDLE *log)
|
||||
{
|
||||
char namebuf[FN_REFLEN];
|
||||
int result;
|
||||
unsigned int i;
|
||||
char *buf_old, *buf_new, *tmp;
|
||||
|
||||
memcpy(namebuf, log->path, log->path_len);
|
||||
|
||||
buf_new= logname(log, namebuf, log->rotations);
|
||||
buf_old= log->path;
|
||||
for (i=log->rotations-1; i>0; i--)
|
||||
{
|
||||
logname(log, buf_old, i);
|
||||
if (!access(buf_old, F_OK) &&
|
||||
(result= my_rename(buf_old, buf_new, MYF(0))))
|
||||
goto exit;
|
||||
tmp= buf_old;
|
||||
buf_old= buf_new;
|
||||
buf_new= tmp;
|
||||
}
|
||||
if ((result= my_close(log->file, MYF(0))))
|
||||
goto exit;
|
||||
namebuf[log->path_len]= 0;
|
||||
result= my_rename(namebuf, logname(log, log->path, 1), MYF(0));
|
||||
log->file= my_open(namebuf, LOG_FLAGS, MYF(0));
|
||||
exit:
|
||||
errno= my_errno;
|
||||
return log->file < 0 || result;
|
||||
}
|
||||
|
||||
|
||||
int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
|
||||
{
|
||||
int result;
|
||||
my_off_t filesize;
|
||||
char cvtbuf[1024];
|
||||
size_t n_bytes;
|
||||
|
||||
mysql_mutex_lock(&log->lock);
|
||||
if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
|
||||
((unsigned long long)filesize >= log->size_limit &&
|
||||
do_rotate(log)))
|
||||
{
|
||||
result= -1;
|
||||
errno= my_errno;
|
||||
goto exit; /* Log rotation needed but failed */
|
||||
}
|
||||
|
||||
n_bytes= my_vsnprintf(cvtbuf, sizeof(cvtbuf), fmt, ap);
|
||||
if (n_bytes >= sizeof(cvtbuf))
|
||||
n_bytes= sizeof(cvtbuf) - 1;
|
||||
|
||||
result= my_write(log->file, (uchar *) cvtbuf, n_bytes, MYF(0));
|
||||
|
||||
exit:
|
||||
mysql_mutex_unlock(&log->lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int logger_rotate(LOGGER_HANDLE *log)
|
||||
{
|
||||
int result;
|
||||
mysql_mutex_lock(&log->lock);
|
||||
result= do_rotate(log);
|
||||
mysql_mutex_unlock(&log->lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...)
|
||||
{
|
||||
int result;
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
result= logger_vprintf(log, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
void init_logger_mutexes()
|
||||
{
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
if (PSI_server)
|
||||
PSI_server->register_mutex("sql_logger", mutex_list, 1);
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user