dovecot: Added mail_log_events, mail_log_group_events and mail_l...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Jun 21 00:51:42 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/ea050869097b
changeset: 5794:ea050869097b
user: Timo Sirainen <tss at iki.fi>
date: Thu Jun 21 00:51:34 2007 +0300
description:
Added mail_log_events, mail_log_group_events and mail_log_fields settings to
mail_log plugin.
diffstat:
2 files changed, 389 insertions(+), 21 deletions(-)
dovecot-example.conf | 8
src/plugins/mail-log/mail-log-plugin.c | 402 ++++++++++++++++++++++++++++++--
diffs (truncated from 493 to 300 lines):
diff -r 512f8982ae8b -r ea050869097b dovecot-example.conf
--- a/dovecot-example.conf Wed Jun 20 23:50:38 2007 +0300
+++ b/dovecot-example.conf Thu Jun 21 00:51:34 2007 +0300
@@ -1103,4 +1103,12 @@ plugin {
# they're moved to a 3rd namespace. The mails won't be counted in quota,
# and they're not deleted automatically (use a cronjob or something).
#lazy_expunge = .EXPUNGED/ .DELETED/ .DELETED/.EXPUNGED/
+
+ # Events to log. Default is all.
+ #mail_log_events = delete undelete expunge copy mailbox_delete
+ # Group events within a transaction to one line.
+ #mail_log_group_events =
+ # Available fields: uid, box, msgid, size, vsize
+ # size and vsize are available only for expunge and copy events.
+ #mail_log_fields = uid box msgid size
}
diff -r 512f8982ae8b -r ea050869097b src/plugins/mail-log/mail-log-plugin.c
--- a/src/plugins/mail-log/mail-log-plugin.c Wed Jun 20 23:50:38 2007 +0300
+++ b/src/plugins/mail-log/mail-log-plugin.c Thu Jun 21 00:51:34 2007 +0300
@@ -2,10 +2,13 @@
#include "lib.h"
#include "array.h"
+#include "str.h"
#include "str-sanitize.h"
#include "mail-storage-private.h"
#include "mailbox-list-private.h"
#include "mail-log-plugin.h"
+
+#include <stdlib.h>
#define MAILBOX_NAME_LOG_LEN 64
#define MSGID_LOG_LEN 80
@@ -17,7 +20,73 @@
#define MAIL_LOG_LIST_CONTEXT(obj) \
MODULE_CONTEXT(obj, mail_log_mailbox_list_module)
+enum mail_log_field {
+ MAIL_LOG_FIELD_UID = 0x01,
+ MAIL_LOG_FIELD_BOX = 0x02,
+ MAIL_LOG_FIELD_MSGID = 0x04,
+ MAIL_LOG_FIELD_PSIZE = 0x08,
+ MAIL_LOG_FIELD_VSIZE = 0x10
+};
+#define MAIL_LOG_DEFAULT_FIELDS \
+ (MAIL_LOG_FIELD_UID | MAIL_LOG_FIELD_BOX | \
+ MAIL_LOG_FIELD_MSGID | MAIL_LOG_FIELD_PSIZE)
+
+enum mail_log_event {
+ MAIL_LOG_EVENT_DELETE = 0x01,
+ MAIL_LOG_EVENT_UNDELETE = 0x02,
+ MAIL_LOG_EVENT_EXPUNGE = 0x04,
+ MAIL_LOG_EVENT_COPY = 0x08,
+ MAIL_LOG_EVENT_MAILBOX_DELETE = 0x10,
+
+ MAIL_LOG_EVENT_MASK_ALL = 0x1f
+};
+#define MAIL_LOG_DEFAULT_EVENTS MAIL_LOG_EVENT_MASK_ALL
+
+static const char *field_names[] = {
+ "uid",
+ "box",
+ "msgid",
+ "size",
+ "vsize",
+ NULL
+};
+
+static const char *event_names[] = {
+ "delete",
+ "undelete",
+ "expunge",
+ "copy",
+ "mailbox_delete",
+ NULL
+};
+
+struct mail_log_settings {
+ enum mail_log_field fields;
+ enum mail_log_event events;
+
+ unsigned int group_events:1;
+};
+
+struct mail_log_group_changes {
+ enum mail_log_event event;
+ const char *data;
+
+ ARRAY_TYPE(seq_range) uids;
+ uoff_t psize_total, vsize_total;
+};
+
+struct mail_log_transaction_context {
+ union mailbox_transaction_module_context module_ctx;
+ pool_t pool;
+
+ ARRAY_DEFINE(group_changes, struct mail_log_group_changes);
+
+ unsigned int changes;
+};
+
const char *mail_log_plugin_version = PACKAGE_VERSION;
+
+static struct mail_log_settings mail_log_set;
static void (*mail_log_next_hook_mail_storage_created)
(struct mail_storage *storage);
@@ -30,24 +99,225 @@ static MODULE_CONTEXT_DEFINE_INIT(mail_l
static MODULE_CONTEXT_DEFINE_INIT(mail_log_mailbox_list_module,
&mailbox_list_module_register);
-static void mail_log_action(struct mail *mail, const char *action)
-{
- const char *msgid, *mailbox_str;
-
- mailbox_str = mailbox_get_name(mail->box);
- if (strcmp(mailbox_str, "INBOX") == 0) {
- /* most operations are for INBOX, and POP3 has only INBOX,
- so don't add it. */
- mailbox_str = "";
- } else {
- mailbox_str = str_sanitize(mailbox_str, 80);
- mailbox_str = t_strconcat(", box=", mailbox_str, NULL);
- }
-
- msgid = mail_get_first_header(mail, "Message-ID");
- i_info("%s: uid=%u, msgid=%s%s", action, mail->uid,
- msgid == NULL ? "(null)" : str_sanitize(msgid, MSGID_LOG_LEN),
- mailbox_str);
+static enum mail_log_field mail_log_field_find(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; field_names[i] != NULL; i++) {
+ if (strcmp(name, field_names[i]) == 0)
+ return 1 << i;
+ }
+ return 0;
+}
+
+static enum mail_log_event mail_log_event_find(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; event_names[i] != NULL; i++) {
+ if (strcmp(name, event_names[i]) == 0)
+ return 1 << i;
+ }
+ return 0;
+}
+
+static const char *mail_log_event_get_name(enum mail_log_event event)
+{
+ unsigned int i;
+
+ for (i = 0; event_names[i] != NULL; i++) {
+ if ((unsigned)event == (unsigned)(1 << i))
+ return event_names[i];
+ }
+ i_unreached();
+ return NULL;
+}
+
+static struct mail_log_group_changes *
+mail_log_action_get_group(struct mail_log_transaction_context *lt,
+ enum mail_log_event event, const char *data)
+{
+ struct mail_log_group_changes *group;
+ unsigned int i, count;
+
+ if (!array_is_created(<->group_changes))
+ p_array_init(<->group_changes, lt->pool, 8);
+
+ group = array_get_modifiable(<->group_changes, &count);
+ for (i = 0; i < count; i++) {
+ if (group[i].event == event &&
+ null_strcmp(data, group[i].data) == 0)
+ return &group[i];
+ }
+
+ group = array_append_space(<->group_changes);
+ group->event = event;
+ group->data = p_strdup(lt->pool, data);
+ return group;
+}
+
+static void
+mail_log_action_add_group(struct mail_log_transaction_context *lt,
+ struct mail *mail, enum mail_log_event event,
+ const char *data)
+{
+ struct mail_log_group_changes *group;
+ uoff_t size;
+
+ group = mail_log_action_get_group(lt, event, data);
+
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0) {
+ if (!array_is_created(&group->uids))
+ p_array_init(&group->uids, lt->pool, 32);
+ seq_range_array_add(&group->uids, 0, mail->uid);
+ }
+
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 &&
+ (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
+ size = mail_get_physical_size(mail);
+ if (size != (uoff_t)-1)
+ group->psize_total += size;
+ }
+
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 &&
+ (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) {
+ size = mail_get_virtual_size(mail);
+ if (size != (uoff_t)-1)
+ group->vsize_total += size;
+ }
+}
+
+static void mail_log_append_mailbox_name(string_t *str, struct mailbox *box)
+{
+ const char *mailbox_str;
+
+ /* most operations are for INBOX, and POP3 has only INBOX,
+ so don't add it. */
+ mailbox_str = mailbox_get_name(box);
+ if (strcmp(mailbox_str, "INBOX") != 0) {
+ str_printfa(str, "box=%s, ",
+ str_sanitize(mailbox_str, MAILBOX_NAME_LOG_LEN));
+ }
+}
+
+static void
+mail_log_group(struct mailbox *box, const struct mail_log_group_changes *group)
+{
+ const struct seq_range *range;
+ unsigned int i, count;
+ string_t *str;
+
+ t_push();
+
+ str = t_str_new(128);
+ str_printfa(str, "%s: ", mail_log_event_get_name(group->event));
+
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_UID) != 0 &&
+ array_is_created(&group->uids)) {
+ str_append(str, "uids=");
+
+ range = array_get(&group->uids, &count);
+ for (i = 0; i < count; i++) {
+ if (i != 0)
+ str_append_c(str, ',');
+
+ str_printfa(str, "%u", range[i].seq1);
+ if (range[i].seq1 != range[i].seq2)
+ str_printfa(str, "-%u", range[i].seq2);
+ }
+ str_append(str, ", ");
+ }
+
+ if ((mail_log_set.fields & MAIL_LOG_FIELD_BOX) != 0)
+ mail_log_append_mailbox_name(str, box);
+
+ if (group->event == MAIL_LOG_EVENT_COPY)
+ str_printfa(str, "dest=%s, ", group->data);
+
+ if (group->psize_total != 0)
+ str_printfa(str, "size=%"PRIuUOFF_T", ", group->psize_total);
+ if (group->vsize_total != 0)
+ str_printfa(str, "size=%"PRIuUOFF_T", ", group->vsize_total);
+ str_truncate(str, str_len(str)-2);
+
+ i_info("%s", str_c(str));
+ t_pop();
+}
+
+static void
+mail_log_group_changes(struct mailbox *box,
+ struct mail_log_transaction_context *lt)
+{
+ const struct mail_log_group_changes *group;
+ unsigned int i, count;
+
+ group = array_get(<->group_changes, &count);
+ for (i = 0; i < count; i++)
+ mail_log_group(box, &group[i]);
+}
+
+static void mail_log_action(struct mail *mail, enum mail_log_event event,
+ const char *data)
+{
+ struct mail_log_transaction_context *lt =
+ MAIL_LOG_CONTEXT(mail->transaction);
+ const char *msgid;
+ uoff_t size;
+ string_t *str;
+ pool_t pool;
+
+ if ((mail_log_set.events & event) == 0)
+ return;
+
+ if (lt == NULL) {
More information about the dovecot-cvs
mailing list