# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved. smarter_mail = { plugin_version = "1.1" info.1.manufacturer = "SmarterTools" info.1.device = "SmarterMail" info.1.version.1 = "5" # 2008-06-04 - 1.0 - GMF - Initial implementation # 2009-02-13 - 1.1 - gas - aded support for dots seperating dates # The name of the log format log.format.format_label = "SmarterMail Log Format" log.miscellaneous.log_data_type = "mail_server" log.miscellaneous.log_format_type = "mail_server" # The log is in this format if any of the first ten lines match this regular expression log.format.autodetect_regular_expression = "^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] [[][0-9]+[.][0-9]+[.][0-9]+[.][0-9]+[]][[][0-9]+[]] (rsp:|connected|cmd:) " # All log field parsing will be done using the parsing filters log.format.parse_only_with_filters = "true" # Log fields log.fields = { date = "" time = "" source_ip.type = "host" sender = "" recipient = "" server_domain = "" server_response = "" error_message = "" messages_queued = "" messages_delivered = "" messages_failed = "" bytes_queued = "" bytes_delivered = "" } # log.fields log.parsing_filters.parse = ` if (matches_regular_expression(current_log_line(), "^([0-9][0-9]:[0-9][0-9]:[0-9][0-9]) [[]([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)[]][[]([0-9]+)[]] (rsp:|connected|cmd:) (.*)$")) then ( v.key = $3; v.command = $4; v.remainder = $5; set_collected_field(v.key, 'time', $1); set_collected_field(v.key, 'source_ip', $2); # Handle connection lines if ((v.command eq "connected") and matches_regular_expression(v.remainder, "^at ([0-9/.]+)")) then ( set_collected_field(v.key, 'date', $1); ); # Handle cmd lines if (v.command eq "cmd:") then ( # Handle HELO/EHLO lines if (matches_regular_expression(v.remainder, '^([Hh][Ee][Ll][Oo]|[Ee][Hh][Ll][Oo]) (.*)$')) then set_collected_field(v.key, 'server_domain', $2); # Handle MAIL FROM lines if (matches_regular_expression(v.remainder, "^[Mm][Aa][Ii][Ll] [Ff][Rr][Oo][Mm]:<([^>]+)>(.*)")) then ( set_collected_field(v.key, 'sender', $1); v.remainder = $2; set_collected_field(v.key, 'messages_queued', 1); if (matches_regular_expression(v.remainder, "^ *[Ss][Ii][Zz][Ee]=([0-9]+)")) then ( set_collected_field(v.key, 'bytes_queued', $1); ); accept_collected_entry(v.key, true); ); # MAIL FROM # Handle RCPT TO lines else if (matches_regular_expression(v.remainder, "^[Rr][Cc][Pp][Tt] [Tt][Oo]:<([^>]+)>")) then ( set_collected_field(v.key, 'last_message', "RCPT TO"); set_collected_field(v.key, 'recipient', $1); v.remainder = $2; set_collected_field(v.key, 'messages_delivered', get_collected_field(v.key, 'messages_queued')); set_collected_field(v.key, 'bytes_delivered', get_collected_field(v.key, 'bytes_queued')); set_collected_field(v.key, 'messages_delivered', 1); set_collected_field(v.key, 'messages_queued', 0); set_collected_field(v.key, 'bytes_queued', 0); ); # RCPT TO ); # if cmd: else if (v.command eq "rsp:") then ( if (get_collected_field(v.key, "last_message") eq "RCPT TO") then ( if (matches_regular_expression(v.remainder, "^([0-9][0-9][0-9]) .*$")) then ( set_collected_field(v.key, "server_response", $1); # If it's a 500, mark it as an error if (matches_regular_expression(v.remainder, "^(5[0-9][0-9] .*)")) then ( set_collected_field(v.key, "error_message", $1); set_collected_field(v.key, 'messages_delivered', 0); set_collected_field(v.key, 'bytes_delivered', 0); set_collected_field(v.key, 'messages_failed', 1); ); # if 500 accept_collected_entry(v.key, true); ); # if code ); # if last message was RCPT TO ); # if rsp: ); # if matches known log data ` # Database fields database.fields = { date_time = "" day_of_week = "" hour_of_day = "" source_ip = "" sender = "" recipient = "" server_domain = "" server_response = "" error_message = "" } # database.fields database.numerical_fields = { messages_queued = { default = true } messages_delivered = { default = true } messages_failed = { default = true } bytes_queued = { type = "float" display_format_type = "bandwidth" } # bytes_queued bytes_delivered = { type = "float" display_format_type = "bandwidth" } # bytes_delivered } # database.numerical_fields # log.filters = { # # } # log.filters create_profile_wizard_options = { # This shows which numerical fields are related to which non-numerical fields. database_field_associations = { error_message = { messages_failed = true } } # database_field_associations # How the reports should be grouped in the report menu report_groups = { date_time_group = "" } # report_groups } # create_profile_wizard_options } # smarter_mail