# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved. iisweb_with_syslog = { plugin_version = "1.2" info.1.manufacturer = "Microsoft" info.1.device = "IIS (with syslog)" info.1.version = "6" # 2008-06-06 - 1.0 - GMF - Initial implementation (copied from iisweb.cfg, and modified for syslog stuff). # 2010-05-10 - 1.1 - Benson - Fixed if date format have a space character like "May 9 2010". # 2010-10-01 - 1.2 - MSG - Edited info lines # The name of the log format log.format.format_label = "IIS Extended (W3C) Web Server Log Format (logged through a syslog server)" log.miscellaneous.log_data_type = "syslog_required" log.miscellaneous.log_format_type = "web_server" # Autodetect based on the Software line, but require a character before it, so it won't match normal IIS data. log.format.autodetect_regular_expression = ".#Software: Microsoft Internet Information (Server|Services) [4-9]" # Look through a lot of lines to try to find a #Fields line log.format.autodetect_lines = "1000" # IIS uses does not use quotes to quote fields, so treat them as actual field values if we see them log.format.ignore_quotes = "true" log.format.parse_only_with_filters = "true" # Log fields log.fields.broken_link = "" # Database fields database.fields.broken_link = "" # Parse W3C header when we find it (during profile creation). log.filter_preprocessor = ` if (!node_exists('v.initialized')) then ( v.initialized = true; include 'util.parse_w3c'; ); # if not initialized if (matches_regular_expression(current_log_line(), '.#Fields: (.*)$')) then ( string fields = $1; #echo("fields: " . fields); parse_w3c_fields(fields); # Trim trailing spaces if (matches_regular_expression(fields, '^(.*[^ ]+) *$')) then fields = $1; # Build a regular expression to detect these lines node field; string regexp = "^"; string field_setting_code = ""; int field_number = 1; v.fields_node = ''; split(fields, ' ', 'v.fields_node'); # echo('fields_node: ' . node_as_string('v.fields_node')); # foreach field ('profiles.' . volatile.new_profile_name . '.log.fields') ( foreach field 'v.fields_node' ( string field_name = replace_all(node_value(field), '-', '_'); # echo("log field: " . field_name); if (regexp ne "^") then regexp .= " "; regexp .= "([^ ]+)"; field_setting_code .= " set_collected_field('', '" . field_name . "', $" . field_number . ");\n"; field_number++; # echo(field); ); # echo("regexp: " . regexp); # Build the parsing filter to extract this data string filter_code = " if (matches_regular_expression(v.syslog_message, '" . regexp . "')) then ( " . field_setting_code . " accept_collected_entry('', false); ); "; # Install the filter in the new profile, if we're creating one, or the current profile, if we're building a database #debug echo("filter_code: " . filter_code); if (node_exists('volatile.new_profile_name')) then ('profiles.' . volatile.new_profile_name . '.log.parsing_filters.parse_data_line') = filter_code; else ('profiles.' . internal.profile_name . '.log.parsing_filters.parse_data_line') = filter_code; 'reject'; ); # if #Fields # Don't parse any other # lines as data lines else if (starts_with(current_log_line(), '#')) then ( 'reject'; ); ` log.parsing_filters.remove_date_time = ` if (matches_regular_expression(v.syslog_message, '^[A-Z][a-z][a-z] [0-9| ][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^ ]+ [^[]+[[][^]]+[]] (.*)$')) then v.syslog_message = $1; ` log.parsing_filters.parse_data_line = ` error("No #Fields line detected in syslog data--cannot parse log data without a #Fields line"); ` # Get search engine and search phrase information from the referrer field (before it gets simplified). log.parsing_filters.compute_se_sp = { value = ` if (get_search_engine_info(referrer)) then ( search_engine = volatile.search_engine; search_phrase = volatile.search_phrase; ); ` requires_fields = { referrer = true } } # Get web browser, operating system, web browser, and spider information from the user-agent field. log.parsing_filters.derive_from_user_agent = { value = `get_user_agent_info(replace_all(cs_user_agent, '+', ' ')); web_browser = volatile.web_browser; operating_system = volatile.operating_system; spider = volatile.spider; ` requires_fields = { cs_user_agent = true } } # Log Filters log.filters = { detect_broken_links = { label = "$lang_admin.log_filters.detect_broken_links_label" comment = "$lang_admin.log_filters.detect_broken_links_comment" value = "if (sc_status eq '404') then broken_link = cs_uri_stem;" requires_fields = { sc_status = true cs_uri_stem = true } } # detect_broken_links not_authenticated = { label = "$lang_admin.log_filters.not_authenticated_label" comment = "$lang_admin.log_filters.not_authenticated_comment" value = "if (cs_username eq '-') then cs_username = '(not authenticated)';" requires_fields = { cs_username = true } } # not_authenticated simplify_referrer = { label = "$lang_admin.log_filters.simplify_referrer_label" comment = "$lang_admin.log_filters.simplify_referrer_comment" value = "if (referrer eq '-') then referrer = '(no referrer)' else if (matches_regular_expression(referrer, '^([^:]+://[^/]+/)')) then referrer = $1 . '(omitted)'" requires_fields = { referrer = true } } # simplify_referrer internal_referrer = { label = "$lang_admin.log_filters.internal_referrer_label" comment = "$lang_admin.log_filters.internal_referrer_comment" value = "if (contains(referrer, 'mydomain.com/')) then referrer = '(internal referrer)';" disabled = true requires_fields = { referrer = true } } # internal_referrer set_page_for_worm = { label = "$lang_admin.log_filters.set_page_for_worm_label" comment = "$lang_admin.log_filters.set_page_for_worm_comment" value = "if (starts_with(worm, '(')) then '' else cs_uri_stem = '(worm)';" requires_fields = { # cs_uri_stem = true worm = true } } # set_page_for_worm # This filter tacks the page parameters ("URL query") onto the end of the page field empty_uri_query = { label = "$lang_admin.log_filters.empty_uri_query_label" comment = "$lang_admin.log_filters.empty_uri_query_comment" value = "if (cs_uri_query eq '-') then cs_uri_query = '(empty)';" disabled = true requires_fields = { cs_uri_query = true } } # empty_uri_query add_cs_uri_query = { label = "$lang_admin.log_filters.add_cs_uri_query_label" comment = "$lang_admin.log_filters.add_cs_uri_query_comment" value = "cs_uri_stem = cs_uri_stem . '?' . cs_uri_query" disabled = true requires_fields = { cs_uri_query = true cs_uri_stem = true } } # add_cs_uri_query detect_page_views = { label = '$lang_admin.log_filters.detect_page_views_label' comment = '$lang_admin.log_filters.detect_page_views_comment' value = "if ((file_type eq 'JPEG') or (file_type eq 'JPG') or (file_type eq 'GIF') or (file_type eq 'ICO') or (file_type eq 'PNG') or (file_type eq 'CSS') or (file_type eq 'SWF') or (file_type eq 'JS')) then page_views = 0; else page_views = 1;" requires_fields = { file_type = true } } # detect_page_views strip_non_page_views = { label = '$lang_admin.log_filters.strip_non_page_views_label' comment = '$lang_admin.log_filters.strip_non_page_views_comment' value = "if (page_views == 0) then cs_uri_stem = substr(cs_uri_stem, 0, last_index(cs_uri_stem, '/') + 1) . '(nonpage)';" requires_fields = { cs_uri_stem = true } } # strip_non_page_views mark_entry = { label = '$lang_admin.log_filters.mark_entry_label' comment = '$lang_admin.log_filters.mark_entry_comment' value = 'hits = 1;' } # mark_entry } # log.filters log.field_options = { sessions_page_field = "cs_uri_stem" sessions_visitor_id_field = "c_ip" sessions_event_field = "page_views" } # log.field_options database.numerical_fields = { hits = { label = "$lang_stats.field_labels.hits" default = false requires_log_field = false type = "int" display_format_type = "integer" entries_field = true } # hits page_views = { label = "$lang_stats.field_labels.page_views" default = true requires_log_field = false type = "int" display_format_type = "integer" } # page_views visitors = { label = "$lang_stats.field_labels.visitors" default = false requires_log_field = true log_field = "c_ip" type = "unique" display_format_type = "integer" } # visitors sc_bytes = { label = "$lang_stats.field_labels.sc_bytes" default = false log_field = "sc_bytes" requires_log_field = true type = "int" integer_bits = 64 display_format_type = "bandwidth" } cs_bytes = { label = "$lang_stats.field_labels.cs_bytes" default = false log_field = "cs_bytes" requires_log_field = true type = "int" integer_bits = 64 display_format_type = "bandwidth" } time_taken = { label = $lang_stats.field_labels.time_taken default = false requires_log_field = true type = "int" integer_bits = 64 display_format_type = duration_milliseconds } # time_taken time_taken_avg = { label = "$lang_stats.field_labels.average $lang_stats.field_labels.time_taken" default = false log_field = "time_taken" requires_log_field = true type = "int" integer_bits = 64 aggregation_method = "average" average_denominator_field = "hits" display_format_type = duration_milliseconds } # time_taken } # 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_type = true cs_uri_stem = true cs_uri_query = true broken_link = true } visitor_demographics_group = { c_ip = true domain_description = true location = true organization = true isp = true domain = true cs_username = true } visitor_systems_group = { screen_dimensions = true screen_depth = true web_browser = true operating_system = true } referrer_group = { referrer = true search_engine = true search_phrase = true referrer_description = true search_phrase_by_search_engine = true } server_group = { s_sitename = true s_computername = true s_ip = true s_port = true cs_host = true } other_group = { cs_version = true worm = true spider = true cs_method = true sc_status = true sc_substatus = true sc_win32_status = true cs_cookie = true } } # report_groups final_step = ` include "templates.admin.profiles.setup_reports_util"; string profile = "profiles." . volatile.new_profile_name; # Remove cs_uri_query and cs_cookie from the database fields delete_database_field(profile, 'cs_uri_query'); delete_database_field(profile, 'cs_cookie'); # Create the standard reports add_standard_reports(profile); # Delete referrer filters if there's no referrer field if (!node_exists(profile . ".database.fields.referrer")) then ( (profile . ".log.filters.no_referrer.disabled") = true; (profile . ".log.filters.internal_referrer.disabled") = true; ); ` # end final_step } # create_profile_wizard_options ## ## Uncommenting this section will provide enhanced granularity visitor tracking by over-riding ## default visitor tracking and uniqueness using c_ip with c_ip + cs_user_agent in ## all reports including sessions analysis reporting ## ## log.fields.visitor_id = "" ## database.fields.visitor_id = "" ## database.numerical_fields.visitors.log_field = "visitor_id" ## ## log.filters.visitor_id = { ## label = 'Client IP + user Agent' ## comment = 'Provides better tracking of unique visitors when multiple users are coming from the same client IP (ISP/NAT/FIREWALL/ROUTER)' ## value = 'visitor_id = c_ip . "+" . cs_user_agent;' ## } # log.filters.visitor_id ## ## log.field_options.sessions_visitor_id_field = "visitor_id" } # iisweb_with_syslog