bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen#define TEST_LOG_MSG_PREFIX "This is Dovecot's "
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainencmd_log_test(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen unsigned int i;
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen master_service->flags |= MASTER_SERVICE_FLAG_DONT_LOG_TO_STDERR;
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen master_service_init_log(master_service, "doveadm: ");
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen for (i = 0; i < LAST_LOG_TYPE; i++) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen const char *prefix = failure_log_type_prefixes[i];
67d86acc16b837a01d0967b65fc9a81ccf54ef0bTimo Sirainen /* add timestamp so that syslog won't just write
67d86acc16b837a01d0967b65fc9a81ccf54ef0bTimo Sirainen "repeated message" text */
2303ad68175883aaebd1f3b18e69593c2422c7bbTimo Sirainen i_log_type(&ctx, TEST_LOG_MSG_PREFIX"%s log (%u)",
67d86acc16b837a01d0967b65fc9a81ccf54ef0bTimo Sirainen (unsigned int)ioloop_time);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic void cmd_log_reopen(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* 1 << enum log_type */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen HASH_TABLE(char *, struct log_find_file *) files;
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic void cmd_log_find_add(struct log_find_context *ctx,
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen file = p_new(ctx->pool, struct log_find_file, 1);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainencmd_log_find_syslog_files(struct log_find_context *ctx, const char *path)
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* recursively go through all subdirectories */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen cmd_log_find_syslog_files(ctx, str_c(full_path));
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen file = p_new(ctx->pool, struct log_find_file, 1);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic bool log_type_find(const char *str, enum log_type *type_r)
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i;
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen for (i = 0; i < LAST_LOG_TYPE; i++) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen if (strncasecmp(str, failure_log_type_prefixes[i], len) == 0 &&
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic void cmd_log_find_syslog_file_messages(struct log_find_file *file)
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen input = i_stream_create_fd_autoclose(&fd, 1024);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* <type> log */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic void cmd_log_find_syslog_messages(struct log_find_context *ctx)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, ctx->files, &key, &file)) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainencmd_log_find_syslog(struct log_find_context *ctx, int argc, char *argv[])
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen else if (stat("/var/log", &st) == 0 && S_ISDIR(st.st_mode))
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen else if (stat("/var/adm", &st) == 0 && S_ISDIR(st.st_mode))
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen printf("Looking for log files from %s\n", log_dir);
0beef9bf818accfb629a92ef53ff0f6a15005941Timo Sirainen /* give syslog some time to write the messages to files */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenstatic void cmd_log_find(int argc, char *argv[])
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen unsigned int i;
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen ctx.pool = pool_alloconly_create("log file", 1024*32);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&ctx.files, ctx.pool, 0, str_hash, strcmp);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* first get the paths that we know are used */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen set = master_service_settings_get(master_service);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen cmd_log_find_add(&ctx, log_file_path, LOG_TYPE_WARNING);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen cmd_log_find_add(&ctx, log_file_path, LOG_TYPE_ERROR);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen cmd_log_find_add(&ctx, log_file_path, LOG_TYPE_FATAL);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (strcmp(set->info_log_path, "syslog") != 0) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen cmd_log_find_add(&ctx, log_file_path, LOG_TYPE_INFO);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (strcmp(set->debug_log_path, "syslog") != 0) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen cmd_log_find_add(&ctx, log_file_path, LOG_TYPE_DEBUG);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* at least some logs were logged via syslog */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen /* print them */
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen for (i = 0; i < LAST_LOG_TYPE; i++) {
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, ctx.files, &key, &file)) {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen printf("%s%s\n", failure_log_type_prefixes[i],
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen printf("%sNot found\n", failure_log_type_prefixes[i]);
8fdbe2f47df7cbe4ffe163e7c13f52d2649a0dfbAki Tuomistatic const char *t_cmd_log_error_trim(const char *orig)
96f35f249ab0d8d19c5201f6e6c850514ad36971Timo Sirainen /* Trim whitespace from suffix and remove ':' if it exists */
96f35f249ab0d8d19c5201f6e6c850514ad36971Timo Sirainen return orig[pos] == '\0' ? orig : t_strndup(orig, pos);
8f0c238dcbbfa3b984b102260a2440adac667ae8Timo Sirainenstatic void cmd_log_error_write(const char *const *args, time_t min_timestamp)
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen /* <type> <timestamp> <prefix> <text> */
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen /* find type's prefix */
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen for (type = 0; type < LOG_TYPE_COUNT; type++) {
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen if (strcmp(args[0], failure_log_type_names[type]) == 0) {
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen type_prefix = failure_log_type_prefixes[type];
8fdbe2f47df7cbe4ffe163e7c13f52d2649a0dfbAki Tuomi doveadm_print(t_strflocaltime(LOG_TIMESTAMP_FORMAT, t));
8f0c238dcbbfa3b984b102260a2440adac667ae8Timo Sirainenstatic void cmd_log_errors(int argc, char *argv[])
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen path = t_strconcat(doveadm_settings->base_dir,
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen i_fatal("net_connect_unix(%s) failed: %m", path);
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen input = i_stream_create_fd_autoclose(&fd, (size_t)-1);
8fdbe2f47df7cbe4ffe163e7c13f52d2649a0dfbAki Tuomi doveadm_print_formatted_set_format("%{timestamp} %{type}: %{prefix}: %{text}\n");
acba68a69cdd6f3f00faa18cccef356d95048e46Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN {
0ed5452f5fcff082087622e473d790403f66a0e2Aki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_log_errors_ver2 = {
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen unsigned int i;
0ed5452f5fcff082087622e473d790403f66a0e2Aki Tuomi doveadm_cmd_register_ver2(&doveadm_cmd_log_errors_ver2);
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_log); i++)