# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved. serv_uftp = { plugin_version = "1.1" info.1.manufacturer = "Rhino Software" info.1.device = "Serv-U FTP Server" info.1.version.1 = "9.4" # ????-??-?? - ??? - 1.0 - Initial implementation # 2009-07-16 - GMF - 1.0.1 - Removed commas from bandwidth fields # 2010-04-09 - GMF - 1.0.2 - Fixed parsing of Sent lines with commas from bandwidth fields # 2012-04-30 - MSG - 1.1 - Added a parsing filter to extract the disconnect lines # The name of the log format log.format.format_label = "Serv-U FTP Log Format" log.miscellaneous.log_data_type = "ftp" log.miscellaneous.log_format_type = "ftp_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]*\\] [A-Z][a-z][a-z] [0-9][0-9][A-Z][a-z][a-z][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] - (FTP|Sock|\\([0-9]*\\)) " # The format of dates and times in this log log.format.date_format = "ddmmmyy" log.format.time_format = "hh:mm:ss" # All log field parsing will be done using the parsing filters log.format.parse_only_with_filters = "true" # An entry in this log is called an "event" in the statistics (not a "hit") statistics.miscellaneous.entry_name = "events" # Log fields log.fields = { date = { label = "$lang_stats.field_labels.date" type = "date" index = 0 subindex = 0 hierarchy_dividers = "" left_to_right = false leading_divider = "false" } # date time = { label = "$lang_stats.field_labels.time" type = "time" index = 0 subindex = 0 hierarchy_dividers = "" left_to_right = false leading_divider = "false" } # time hostname = { label = "$lang_stats.field_labels.hostname" type = "host" index = 0 subindex = 0 hierarchy_dividers = "." left_to_right = false leading_divider = "false" } # hostname bytes_sent = { label = "$lang_stats.field_labels.bytes_sent" type = "flat" index = 0 subindex = 0 hierarchy_dividers = "" left_to_right = false leading_divider = "false" } # bytes_sent bytes_received = { label = "$lang_stats.field_labels.bytes_received" type = "flat" index = 0 subindex = 0 hierarchy_dividers = "" left_to_right = false leading_divider = "false" } # bytes_received file = { label = "$lang_stats.field_labels.file" type = "page" index = 0 subindex = 0 hierarchy_dividers = "/?" left_to_right = true leading_divider = "true" } # file mode = { label = "$lang_stats.field_labels.mode" type = "flat" index = 0 subindex = 0 } # mode type = { label = "$lang_stats.field_labels.type" type = "flat" index = 0 subindex = 0 } # type event = { label = "$lang_stats.field_labels.event" type = "flat" index = 0 subindex = 0 } # event authenticated_user = { label = "$lang_stats.field_labels.authenticated_user" type = "flat" index = 0 subindex = 0 } # authenticated_user } # log.fields # # Log Parsing Filters log.parsing_filters = { # Parse out all the beginning fields 1 = { label = "1" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] [A-Z][a-z][a-z] ([0-9][0-9][A-Z][a-z][a-z][0-9][0-9]) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9]) - \\\\(([0-9]*)\\\\) ', 'date,time,*KEY*')" } # 1 # Parse out the hostname field from the IP-name field 2 = { label = "2" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) IP-Name: ([^ ]*)', '*KEY*,hostname')" } # 2 # Parse out the hostname on Connected to line 3 = { label = "3" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) Connected to ([^ ]*) ', '*KEY*,hostname')" } # 3 # Parse out the "authenticated user" field 4 = { label = "4" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) USER (.*)$', '*KEY*,authenticated_user')" } # 4 # Parse out the "disconnecting" field disconnecting = { label = "disconnecting" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) .*- (disconnecting)$', '*KEY*,event')" } # disconnecting # Accept the log entry when we see a disconnect line 12 = { label = "12" comment = "" value = "accept_collected_entry_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) .*- (disconnecting)$', '*KEY*,event')" } # 12 # Parse out DELE and RMD lines delete = { label = "4" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (DELE|RMD) (.*)()()$', '*KEY*,event,file,bytes_sent,bytes_received')" } # DELE # Parse out the "authenticated user" field 5 = { label = "5" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) User (.*) logged in$', '*KEY*,authenticated_user')" } # 5 # Parse out the mode field 6 = { label = "6" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) [0-9]* Entering ([^ ]*) Mode', '*KEY*,mode')" } # 6 # Parse out the type field 7 = { label = "7" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) [0-9]* Opening ([^ ]*) mode ', '*KEY*,type')" } # 7 # Parse a transfer line received = { label = "Received file" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (Received file) (.*) successfully \\\\([0-9.]* [A-Za-z]*/sec - ([0-9,]*) [Bb]ytes\\\\)()$', '*KEY*,event,file,bytes_received,bytes_sent')" } # received_file # Parse a transfer line sent_file = { label = "sent file" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (Sent file) (.*) successfully \\\\([0-9,.]* [A-Za-z]*/sec - ([0-9,]*) [Bb]ytes\\\\)()$', '*KEY*,event,file,bytes_sent,bytes_received')" } # sent_file # Accept the log entry when we see a transfer line 9 = { label = "9" comment = "" value = "accept_collected_entry_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (Received|Sent) file', true)" } # 9 # Parse a Error sending line 10 = { label = "10" comment = "" value = "collect_fields_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (Error sending file) (.*), aborting \\\\([0-9.]* [A-Za-z]*/sec - ([0-9,]*) [Bb]ytes()', '*KEY*,event,file,bytes_sent,bytes_received')" } # 10 # Accept the log entry when we see a transfer line 11 = { label = "11" comment = "" value = "accept_collected_entry_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) Error sending file .*, aborting \\\\([0-9.]* [A-Za-z]*/sec - [0-9,]* [Bb]ytes', false)" } # 11 # Accept the log entry when we see a transfer line (carry over in case there are multiple deletions) accept_delete = { label = "accept on delete" comment = "" value = "accept_collected_entry_using_regexp('^\\\\[[0-9]*\\\\] ... ....... ..:..:.. - \\\\(([0-9]*)\\\\) (RMD|DELE)', true)" } # accept_delete } # log.parsing_filters # Database fields database.fields = { date_time = { label = "$lang_stats.field_labels.date_time" log_field = "date_time" type = "string" suppress_top = 0 suppress_bottom = 3 display_format_type = "date_time" } # date_time day_of_week = { label = "$lang_stats.field_labels.day_of_week" log_field = "day_of_week" type = "string" suppress_top = 0 suppress_bottom = 2 display_format_type = "day_of_week" } # day_of_week hour_of_day = { label = "$lang_stats.field_labels.hour_of_day" log_field = "hour_of_day" type = "string" suppress_top = 0 suppress_bottom = 2 display_format_type = "hour_of_day" } # hour_of_day file = { label = "$lang_stats.field_labels.file" log_field = "file" type = "string" suppress_top = 0 suppress_bottom = 9 } # file file_type = { label = "$lang_stats.field_labels.file_type" log_field = "file_type" type = "string" suppress_top = 0 suppress_bottom = 2 } # file_type hostname = { label = "$lang_stats.field_labels.hostname" log_field = "hostname" type = "string" suppress_top = 0 suppress_bottom = 2 display_format_type = "hostname" } # hostname domain_description = { label = "$lang_stats.field_labels.domain_description" log_field = "domain_description" type = "string" suppress_top = 0 suppress_bottom = 2 } # domain_description location = { label = "$lang_stats.field_labels.location" log_field = "location" type = "string" suppress_top = 0 suppress_bottom = 3 } # location authenticated_user = { label = "$lang_stats.field_labels.authenticated_user" log_field = "authenticated_user" type = "string" suppress_top = 0 suppress_bottom = 2 } # authenticated_user mode = { label = "$lang_stats.field_labels.mode" log_field = "mode" type = "string" suppress_top = 0 suppress_bottom = 2 } # mode type = { label = "$lang_stats.field_labels.type" log_field = "type" type = "string" suppress_top = 0 suppress_bottom = 2 } # type event = { label = "$lang_stats.field_labels.event" log_field = "event" type = "string" suppress_top = 0 suppress_bottom = 2 } # event } # database.fields # Log Filters log.filters = { not_authenticated = { label = "$lang_admin.log_filters.not_authenticated_label" comment = "$lang_admin.log_filters.not_authenticated_comment" value = "if (authenticated_user eq '-') then authenticated_user = '(not authenticated)';" } # not_authenticated # This filter converts \ to / in the file field 1 = { label = "1" comment = "" value = "file = replace_all(file, '\\\\', '/');" } # 1 # This filter removes commas from byte fields remove_commas = { label = "Remove Commas" comment = "" value = ` bytes_sent = replace_all(bytes_sent, ',', ''); bytes_received = replace_all(bytes_received, ',', ''); ` } # remove_commas mark_entry = { label = '$lang_admin.log_filters.mark_entry_label' comment = '$lang_admin.log_filters.mark_entry_comment' value = 'events = 1;' } # mark_entry } # log.filters log.field_options = { sessions_page_field = "file" sessions_visitor_id_field = "hostname" sessions_event_field = "events" } # log.field_options database.numerical_fields = { events = { label = "$lang_stats.field_labels.events" default = true requires_log_field = false type = "int" display_format_type = "integer" entries_field = true } # events bytes_sent = { label = "$lang_stats.field_labels.bytes_sent" default = false requires_log_field = true log_field = "bytes_sent" type = "int" integer_bits = 64 display_format_type = "bandwidth" } # bytes_sent bytes_received = { label = "$lang_stats.field_labels.bytes_received" default = false requires_log_field = true log_field = "bytes_received" type = "int" integer_bits = 64 display_format_type = "bandwidth" } # bytes_received } # database.numerical_fields create_profile_wizard_options = { date_time_tracking = true host_tracking = true # How the reports should be grouped in the report menu report_groups = { date_time_group = "" content_group = { file = true file_type = true } visitor_demographics_group = { hostname = true domain_description = true location = true authenticated_user = true } other_group = { mode = true type = true event = true } } # report_groups } # create_profile_wizard_options not_supported = { pageviews = true visitors = true } # not_supported } # serv_uftp