# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved. shoutcast18 = { plugin_version = "1.5" info.1.manufacturer = "Nullsoft" info.1.device = "SHOUTcast Media Server / DNAS (Distributed Network Audio Server)" info.1.version.1 = "1.6" info.1.version.2 = "1.8" info.1.version.3 = "1.9" # 01/Jun/2006 - GMF - 1.1 - cleaned up to remove defaults; changed "country" to "location" # 03/Feb/2009 - gas - 1.2 - modified the parsing regex, v8 complained about the regex # 2010-10-05 - 1.3 - MSG - Edited info lines. # 2010-10-14 - 1.4 - KBB - Changed from parsing regular expression to parsing filter to be able to make sure # the line contains "connection closed" before applying the regular expression. This is to help performance. # 2010-11-09 - 1.5 - KBB - Moved support for shoutcast 1.6 to this plug-in and added player field to retrive # that info from 1.9 logs. No longer checking for "connection closed" before applying regular expressions, # since the player info comes from a different line. Changed field names: hostname => dest and # unique_source_ips => unique_destinations. Used dest and userid as the key to associate the player # with the info on the "connection closed" line. This version has been tested with 1.6 and 1.9 logs. # The name of the log format log.format.format_label = "SHOUTcast Log Format" log.miscellaneous.log_data_type = "generic" log.miscellaneous.log_format_type = "media_server" # The log is in this format if any of the first ten lines match this regular expression log.format.autodetect_regular_expression = "SHOUTcast.*v1.[689].*starting up" # This regular expression is used to parse the log fields out of the log entry # log.format.parsing_regular_expression = "^<([0-9][0-9]/[0-9][0-9]/[0-9][0-9])@([0-9][0-9]:[0-9][0-9]:[0-9][0-9])> .dest: ([0-9.]*). connection closed \\(([0-9]*) seconds\\) \\(UID: ([0-9]*)\\)\\[L: [0-9]*\\].Bytes: ([0-9]*)" # log.format.parsing_regular_expression = "^<([0-9][0-9]/[0-9][0-9]/[0-9][0-9])@([0-9][0-9]:[0-9][0-9]:[0-9][0-9])> .dest: ([0-9.]*). connection closed .([0-9]*) seconds. .UID: ([0-9]*)..L: [0-9]*..Bytes: ([0-9]*)..P: [0-9]+." log.format.parse_only_with_filters = "true" # The format of dates and times in this log log.format.date_format = "mm/dd/yy" log.format.time_format = "h:mm:ss" # Log fields log.fields = { date = "" time = "" dest.type = "host" duration = "" user_id = "" bytes_transferred = "" player = "" } # log.fields # Log Filters log.filters = { 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.parsing_filters.parse = ` v.line = current_log_line(); # Typically we get the date and time and other common elements first, but since so many lines are ignored, # it is more efficient not to get them when we don't need them. if (matches_regular_expression(v.line, "^<([0-9][0-9]/[0-9][0-9]/[0-9][0-9])@([0-9][0-9]:[0-9][0-9]:[0-9][0-9])> .dest: ([0-9.]*). connection closed .([0-9]*) seconds. .UID: ([0-9]*)..L: [0-9]*..Bytes: ([0-9]*)..P: [0-9]+.")) then ( v.key = $3 . "_" . $5; set_collected_field(v.key, 'date', $1); set_collected_field(v.key, 'time', $2); set_collected_field(v.key, 'dest', $3); set_collected_field(v.key, 'duration', $4); set_collected_field(v.key, 'user_id', $5); set_collected_field(v.key, 'bytes_transferred', $6); accept_collected_entry(v.key, false); ); else if (matches_regular_expression(v.line, "^<([0-9][0-9]/[0-9][0-9]/[0-9][0-9])@([0-9][0-9]:[0-9][0-9]:[0-9][0-9])> .dest: ([0-9.]*). connection closed .sent ([0-9]*) ")) then ( set_collected_field('', 'date', $1); set_collected_field('', 'time', $2); set_collected_field('', 'dest', $3); set_collected_field('', 'bytes_transferred', $4); accept_collected_entry('', false); ); #<11/01/10@15:30:20> [dest: 64.12.243.204] starting stream (UID: 0)[L: 1]{A: SHOUTcast Directory Tester}(P: 0) else if (matches_regular_expression(v.line, "^<([0-9][0-9]/[0-9][0-9]/[0-9][0-9])@([0-9][0-9]:[0-9][0-9]:[0-9][0-9])> .dest: ([0-9.]*). starting stream .UID: ([0-9]*)..L: [0-9]*.\\\\{A: ([^}]+)\\\\}.P: [0-9]*.")) then ( v.key = $3 . "_" . $4; set_collected_field(v.key, 'date', $1); set_collected_field(v.key, 'time', $2); set_collected_field(v.key, 'dest', $3); set_collected_field(v.key, 'user_id', $4); set_collected_field(v.key, 'player', replace_all(convert_escapes($5), '+', ' ')); # this is often encoded ); ` # Database fields database.fields = { date_time = "" day_of_week = "" hour_of_day = "" dest = "" domain_description = "" user_id = "" location = "" player = "" } # database.fields database.numerical_fields = { events = { default = true requires_log_field = false entries_field = true } # events unique_destinations = { log_field = "dest" type = "unique" } # unique_destinations duration = { type = "float" display_format_type = "duration_compact" } # duration bytes_transferred = { type = "float" display_format_type = "bandwidth" } # bytes_transferred } # database.numerical_fields create_profile_wizard_options = { # How the reports should be grouped in the report menu report_groups = { date_time_group = "" } # report_groups } # create_profile_wizard_options } # shoutcast18