123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /*
- * Copyright 2023 Vsevolod Stakhov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include "config.h"
- #include "logger.h"
- #include "libserver/cfg_file.h"
- #include "libcryptobox/cryptobox.h"
- #include "unix-std.h"
-
- #include "logger_private.h"
-
- #define CONSOLE_LOG_QUARK g_quark_from_static_string("console_logger")
-
- static const char lf_chr = '\n';
- struct rspamd_console_logger_priv {
- int fd;
- int crit_fd;
- };
-
- /* Copy & paste :( */
- static inline void
- log_time(double now, rspamd_logger_t *rspamd_log, char *timebuf,
- size_t len)
- {
- time_t sec = (time_t) now;
- gsize r;
- struct tm tms;
-
- rspamd_localtime(sec, &tms);
- r = strftime(timebuf, len, "%F %H:%M:%S", &tms);
-
- if (rspamd_log->flags & RSPAMD_LOG_FLAG_USEC) {
- char usec_buf[16];
-
- rspamd_snprintf(usec_buf, sizeof(usec_buf), "%.5f",
- now - (double) sec);
- rspamd_snprintf(timebuf + r, len - r,
- "%s", usec_buf + 1);
- }
- }
-
- void *
- rspamd_log_console_init(rspamd_logger_t *logger, struct rspamd_config *cfg,
- uid_t uid, gid_t gid, GError **err)
- {
- struct rspamd_console_logger_priv *priv;
-
- priv = g_malloc0(sizeof(*priv));
-
- if (logger->flags & RSPAMD_LOG_FLAG_RSPAMADM) {
- priv->fd = dup(STDOUT_FILENO);
- priv->crit_fd = dup(STDERR_FILENO);
- }
- else {
- priv->fd = dup(STDERR_FILENO);
- priv->crit_fd = priv->fd;
- }
-
- if (priv->fd == -1) {
- g_set_error(err, CONSOLE_LOG_QUARK, errno,
- "open_log: cannot dup console fd: %s\n",
- strerror(errno));
- rspamd_log_console_dtor(logger, priv);
-
- return NULL;
- }
-
- if (!isatty(priv->fd)) {
- if (logger->flags & RSPAMD_LOG_FLAG_COLOR) {
- /* Disable colors for not a tty */
- logger->flags &= ~RSPAMD_LOG_FLAG_COLOR;
- }
- }
-
- return priv;
- }
-
- void *
- rspamd_log_console_reload(rspamd_logger_t *logger, struct rspamd_config *cfg,
- gpointer arg, uid_t uid, gid_t gid, GError **err)
- {
- struct rspamd_console_logger_priv *npriv;
-
- npriv = rspamd_log_console_init(logger, cfg, uid, gid, err);
-
- if (npriv) {
- /* Close old */
- rspamd_log_console_dtor(logger, arg);
- }
-
- return npriv;
- }
-
- void rspamd_log_console_dtor(rspamd_logger_t *logger, gpointer arg)
- {
- struct rspamd_console_logger_priv *priv = (struct rspamd_console_logger_priv *) arg;
-
- if (priv->fd != -1) {
- if (priv->fd != priv->crit_fd) {
- /* Two different FD case */
- if (close(priv->crit_fd) == -1) {
- rspamd_fprintf(stderr, "cannot close log crit_fd %d: %s\n",
- priv->crit_fd, strerror(errno));
- }
- }
-
- if (close(priv->fd) == -1) {
- rspamd_fprintf(stderr, "cannot close log fd %d: %s\n",
- priv->fd, strerror(errno));
- }
-
- /* Avoid the next if to be executed as crit_fd is equal to fd */
- priv->crit_fd = -1;
- }
-
- if (priv->crit_fd != -1) {
- if (close(priv->crit_fd) == -1) {
- rspamd_fprintf(stderr, "cannot close log crit_fd %d: %s\n",
- priv->crit_fd, strerror(errno));
- }
- }
-
- g_free(priv);
- }
-
- bool rspamd_log_console_log(const char *module, const char *id,
- const char *function,
- int level_flags,
- const char *message,
- gsize mlen,
- rspamd_logger_t *rspamd_log,
- gpointer arg)
- {
- struct rspamd_console_logger_priv *priv = (struct rspamd_console_logger_priv *) arg;
- int fd, r;
- double now;
-
- if (level_flags & G_LOG_LEVEL_CRITICAL) {
- fd = priv->crit_fd;
- }
- else {
- /* Use stderr if we are in rspamadm mode and severity is more than WARNING */
- if ((rspamd_log->flags & RSPAMD_LOG_FLAG_RSPAMADM) && (level_flags & G_LOG_LEVEL_WARNING)) {
- fd = priv->crit_fd;
- }
- else {
- fd = priv->fd;
- }
- }
-
- #ifndef DISABLE_PTHREAD_MUTEX
- if (rspamd_log->mtx) {
- rspamd_mempool_lock_mutex(rspamd_log->mtx);
- }
- else {
- rspamd_file_lock(fd, FALSE);
- }
- #else
- rspamd_file_lock(fd, FALSE);
- #endif
-
- now = rspamd_get_calendar_ticks();
-
- struct rspamd_logger_iov_ctx iov_ctx;
- memset(&iov_ctx, 0, sizeof(iov_ctx));
- rspamd_log_fill_iov(&iov_ctx, now, module, id,
- function, level_flags, message,
- mlen, rspamd_log);
-
- again:
- r = writev(fd, iov_ctx.iov, iov_ctx.niov);
-
- if (r == -1) {
- if (errno == EAGAIN || errno == EINTR) {
- goto again;
- }
-
- if (rspamd_log->mtx) {
- rspamd_mempool_unlock_mutex(rspamd_log->mtx);
- }
- else {
- rspamd_file_unlock(fd, FALSE);
- }
-
- rspamd_log_iov_free(&iov_ctx);
- return false;
- }
-
- if (rspamd_log->mtx) {
- rspamd_mempool_unlock_mutex(rspamd_log->mtx);
- }
- else {
- rspamd_file_unlock(fd, FALSE);
- }
-
- rspamd_log_iov_free(&iov_ctx);
- return true;
- }
|