# Copyright (c) 2013 Flowerfire, Inc. All Rights Reserved. ecds = { plugin_version = "1.0" info.1.manufacturer = "Cisco" info.1.device = "eCDS" info.1.version = "" # 2013-05-20 - GMF - 1.0 - Initial creation (based on flash_media_server) # The name of the log format log.format.format_label = "Cisco eCDS Log Format" log.miscellaneous.log_data_type = "media_server" 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 = "^s-ip[|]#Fields" # Don't add cs_bytes or sc_bytes fields as database fields initially, even if they're in the header--these will be added by snapons auto_setup.omit_database_fields = "x_duration,x_file_size,x_file_length,x_spos,c_spos" # From http://livedocs.adobe.com/fms/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000181.html # cs-bytes - This field shows the number of bytes transferred from the client to the server. # This information can be used to bill customers per session. To calculate the bandwidth # usage per session, subtract the 'cs-bytes' in the 'connect' event from the 'cs-bytes' in # the 'disconnect' event. # sc-bytes - This field shows the number of bytes transferred from the server to the client. # This information can be used to bill customers per session. To calculate the bandwidth # usage per session, subtract the 'sc-bytes' in the 'connect' event by the 'sc-bytes' in # the 'disconnect' event # cs-stream-bytes - This field shows the number of bytes transferred from the client to the server # per stream. To calculate the bandwidth usage per stream, subtract the 'cs-stream-bytes' # in the 'publish' event by the 'cs-stream-bytes' in the 'unpublish' event. # sc-stream-bytes - This field shows the number of bytes transferred from the server to the client per # stream. To calculate the bandwidth usage per stream, subtract the 'sc-stream-bytes' # in the 'play' event by the 'sc-stream-bytes' in the 'stop' event. # This handles "# Format" lines, and creates log and database fields from them log.filter_preprocessor = ` if (matches_regular_expression(current_log_line(), '^s-ip[|]#Fields: +([^ ].*)$')) then ( string fields = $1; string fieldname; string numerical_fields = "profiles." . internal.profile_name . ".database.numerical_fields"; # This subroutine creates a database field subroutine(create_database_field(string fieldname, int top, int bottom), ( # echo("create_database_field: " . fieldname); # debug debug_message("create_database_field(" . fieldname . ")\n"); string databasefieldpath = "profiles." . internal.profile_name . ".database.fields." . fieldname; (databasefieldpath . "") = ""; node databasefield = databasefieldpath; if (top ne 0) then @databasefield{"suppress_top"} = top; if (bottom ne 0) then @databasefield{"suppress_bottom"} = bottom; # sc_age is an integer field, non-aggregating but with many values. Leave it unnormalized and unindexed. if (fieldname eq "sc_age") then ( @databasefield{"type"} = "int"; @databasefield{"aggregation_method"} = "none"; @databasefield{"index"} = false; ); databasefield; )); subroutine(create_log_field(string fieldname, string type), ( debug_message("create_log_field(" . fieldname . "; type=" . type . ")\n"); string logfieldpath = "profiles." . internal.profile_name . ".log.fields." . fieldname; (logfieldpath . "") = ""; node logfield = logfieldpath; if (type ne '') then set_subnode_value(logfield, "type", type); logfield; )); log.format.parsing_regular_expression = '^'; node log_fields_at_end = new_node(); subroutine(create_log_field_at_end(node log_fields_at_end, string fieldname, string type), ( log_fields_at_end{fieldname}{"type"} = type; )); log.format.parsing_regular_expression = '^([^|]+)[|]'; # Create the s_ip_prefix database field, which is a prefix on each line create_log_field('s_ip_prefix', ''); create_database_field('s_ip_prefix', 0, 0); # Extract the fields on at a time while (matches_regular_expression(fields, '^([^ ]+) (.*)$') or matches_regular_expression(fields, '^([^ ]+)$')) ( string unconverted_fieldname = $1; fields = $2; # Strip quotes from field name, if any if (matches_regular_expression(unconverted_fieldname, '^"(.*)"$')) then unconverted_fieldname = $1; # Clean up the field name fieldname = ''; for (int i = 0; i < length(unconverted_fieldname); i++) ( string c = lowercase(substr(unconverted_fieldname, i, 1)); if (!matches_regular_expression(c, '^[a-z0-9]$')) then c = '_'; fieldname .= c; ); while (matches_regular_expression(fieldname, '^(.*)_$')) fieldname = $1; if (fieldname eq 'cs_uri') then ( fieldname = 'cs_uri_stem'; ); # 2012-08-20 - GMF - In earlier versions of this log format, the client IP field is incorrectly called cs_host. This compensates for that by assuming that whenever cs_host is seen, it really means c_ip. if (fieldname eq 'cs_host') then fieldname = 'c_ip'; #echo("fieldname: " . fieldname); # Get the log field type string log_field_type = ''; if (fieldname eq 'cs_referer') then ( log_field_type = 'url'; ); else if (fieldname eq 'cs_uri_stem') then ( log_field_type = 'page'; ); else if (fieldname eq 'cs_user_agent') then ( log_field_type = 'agent'; ); else if ((fieldname eq 'c_ip') or (fieldname eq "cs_host")) then ( log_field_type = 'host'; ); if (false) then ( ); # Create the log field (but not cs_request, which is really three log fields, created below. # if (fieldname eq "cs_request") then ( # create_log_field('cs_method', ''); # create_log_field('cs_uri_stem', 'page'); # create_log_field('cs_protocol', ''); ## create_log_field_at_end(log_fields_at_end, 'file_type', 'file'); ## create_log_field_at_end(log_fields_at_end, 'screen_dimensions', ''); ## create_log_field_at_end(log_fields_at_end, 'screen_depth', ''); # log.format.parsing_regular_expression .= '([^ ]+) ([^ ]+) ([^ ]+)'; # ); else if (fieldname eq 'cs_referer') then ( create_log_field(fieldname, log_field_type); # create_log_field_at_end(log_fields_at_end, 'search_engine', ''); # create_log_field_at_end(log_fields_at_end, 'search_phrase', ''); log.format.parsing_regular_expression .= '([^ ]+)'; ); else if (fieldname eq 'cs_user_agent') then ( create_log_field(fieldname, log_field_type); # create_log_field_at_end(log_fields_at_end, 'operating_system', ''); # create_log_field_at_end(log_fields_at_end, 'web_browser', ''); # create_log_field_at_end(log_fields_at_end, 'spider', ''); log.format.parsing_regular_expression .= '(.*)'; ); # else if (fieldname eq "time") then ( # create_log_field('date', ''); # create_log_field('time', ''); # log.format.parsing_regular_expression .= '[[]([^:]+):([^ ]+) [^]]+[]]'; # ); else ( create_log_field(fieldname, log_field_type); log.format.parsing_regular_expression .= '([^ ]+)'; ); # If there's another field after this one, add a tab to the regular expression if (length(fields) > 0) then log.format.parsing_regular_expression .= ' '; # Ignore certain fields bool omit_field = false; if ((fieldname eq 'x_duration') or (fieldname eq 'x_file_size') or (fieldname eq 'x_file_length') or (fieldname eq 'x_spos') or (fieldname eq 'c_spos')) then ( omit_field = true; ); # If we're creating a profile, create the database fields too. if (node_exists("volatile.creating_profile") and !omit_field) then ( # Handle time by creating date_time and derived database fields if (fieldname eq "time") then ( create_database_field('date_time', 0, 0); create_database_field('day_of_week', 0, 0); create_database_field('hour_of_day', 0, 0); ); # if time # Ignore date; we create date_time when we see time. else if (fieldname eq "date") then ( ); # Create derived fields for agent else if (fieldname eq "cs_user_agent") then ( # create_database_field('operating_system', 0, 0); # create_database_field('web_browser', 0, 0); # create_database_field('spider', 0, 0); ); # Create database field cs_ip and derived field for client IP else if ((fieldname eq "c_ip") or (fieldname eq "cs_host")) then ( create_database_field(fieldname, 0, 0); # create_database_field('location', 0, 0); ); # Create database field cs_referer and derived fields for referrer else if (fieldname eq "cs_referer") then ( create_database_field('cs_referer', 1, 9); # create_database_field('search_engine', 0, 0); # create_database_field('search_phrase', 0, 0); ); # Create derived file type field # else if (fieldname eq "cs_request") then ( # create_database_field('cs_method', 0, 0); # create_database_field('cs_uri_stem', 0, 9); # create_database_field('file_type', 0, 0); # create_database_field('screen_dimensions', 0, 0); # create_database_field('screen_depth', 0, 0); # create_database_field('cs_protocol', 0, 0); # ); # Don't create a database field for x_origin_fetch_size (is reporting required on this field?) # else if (fieldname eq "x_origin_fetch_size") then ( # ); # Don't add a database field for numerical fields else if (subnode_exists(numerical_fields, fieldname)) then ( debug_message("Not adding numerical field: " . fieldname . "\n"); ); # Create a normal database field else create_database_field(fieldname, 0, 0); ); # if creating profile ); # while another field # Create any final log fields node lfae; foreach lfae log_fields_at_end ( #echo("Final log field creation: " . node_name(lfae)); create_log_field(node_name(lfae), @lfae{"type"}); ); # Don't parse the #Fields line as a data line 'reject'; ); # if # Format # Don't parse any other # lines as data lines else if (starts_with(current_log_line(), '#')) then ( 'reject'; ); ` log.filter_initialization = ` v.last_cs_stream_bytes = ""; v.last_sc_stream_bytes = ""; v.last_sc_bytes = ""; v.last_cs_bytes = ""; float cs_stream_bytes_for_db; float sc_stream_bytes_for_db; float sc_bytes_for_db; float cs_bytes_for_db; string visitor_id; ` log.parsing_filters = { # Logs will have c_ip or c_client_id or both. Set visitor_id, used in other filters # based on whichever is available. c_client_id will be used if both exist. set_visitor_to_c_ip = { value = `visitor_id = replace_all(c_ip, '.', '_');` requires_fields = { c_ip = true } } # set_visitor_to_c_ip # Keep this filter 2nd. c_client_id is the more precise id. set_visitor_to_c_client_id = { value = `visitor_id = c_client_id;` requires_fields = { c_client_id = true } } # set_visitor_to_c_client_id # Don't allow negative cs_bytes # fix_cs_bytes = { # value = ` # if (cs_bytes < 0) then # cs_bytes = 0; #` # requires_fields = { # cs_bytes = true # } # } # fix_cs_bytes # Fix the cs_bytes field by subtracting this value from the previous one (it's a running total, # which otherwise will be aggregated to give too-large numbers). # fix_cs_bytes = { # value = ` #cs_bytes = cs_bytes; # make sure cs_bytes is parsed before we set it, or it might be overwritten by index/subindex parsing ##if (visitor_id ne "(empty)" and visitor_id ne "-") then ( # # #session disconnect 2008-06-13 16:42:59 4882 222.22.222.2 -1746602884 73147 - - - - - # # # If there was a previous value, use the difference in the database entry # v.last_cs_bytes = get_collected_field(visitor_id, 'last_cs_bytes'); # #if (subnode_exists('v.last_cs_bytes', visitor_id)) then ( # if (v.last_cs_bytes ne '') then ( # # # If value is negative due to logging bug (above), then set it to the previous # # value as if there have been no bytes. The result is the same as setting it # # to zero if the x-event is disconnect as it is in all examples seen so far. # if (cs_bytes < 0) then cs_bytes = v.last_cs_bytes; # # cs_bytes_for_db = 0.0 + cs_bytes - v.last_cs_bytes; # if (cs_bytes_for_db < 0) then ( # cs_bytes_for_db = cs_bytes; # ); # ); # else ( # if (cs_bytes < 0) then cs_bytes = 0; # This compensates for a logging bug. # cs_bytes_for_db = cs_bytes; # ); # # # Remember the current cs_bytes value for a later event for this visitor # if (x_event eq "disconnect") then ( # #set_subnode_value('v.last_cs_bytes', visitor_id, 0); # set_collected_field(visitor_id, 'last_cs_bytes', 0); # ); # else ( # #set_subnode_value('v.last_cs_bytes', visitor_id, cs_bytes); # set_collected_field(visitor_id, 'last_cs_bytes', cs_bytes); # ); # # # In the database, the cs_bytes field should be the difference # cs_bytes = cs_bytes_for_db; # #); # if visitor_id #else ( # cs_bytes = 0; #); #` # requires_fields = { # cs_bytes = true # x_event = true # } # } # fix_cs_bytes # Fix the sc_bytes field by subtracting this value from the previous one (it's a running total, # which otherwise will be aggregated to give too-large numbers). # fix_sc_bytes = { # value = ` #sc_bytes = sc_bytes; # make sure sc_bytes is parsed before we set it, or it might be overwritten by index/subindex parsing #if (visitor_id ne "(empty)" and visitor_id ne "-") then ( # # # If there was a previous value, use the difference in the database entry # v.last_sc_bytes = get_collected_field(visitor_id, 'last_sc_bytes'); # #if (subnode_exists('v.last_sc_bytes', visitor_id)) then ( # if (v.last_sc_bytes ne '') then ( # # # Compensates for a logging bug - seen only with cs-bytes so far. # if (sc_bytes < 0) then sc_bytes = v.last_sc_bytes; # # #sc_bytes_for_db = 0.0 + sc_bytes - node_value(subnode_by_name('v.last_sc_bytes', visitor_id)); # sc_bytes_for_db = 0.0 + sc_bytes - v.last_sc_bytes; # if (sc_bytes_for_db < 0) then ( # sc_bytes_for_db = sc_bytes; # ); # ); # else ( # if (sc_bytes < 0) then sc_bytes = 0; # Compensates for a logging bug - seen only with cs-bytes so far. # sc_bytes_for_db = sc_bytes; # ); # # # Remember the current sc_bytes value for a later event for this visitor # if (x_event eq "disconnect") then ( # #set_subnode_value('v.last_sc_bytes', visitor_id, 0); # set_collected_field(visitor_id, 'last_sc_bytes', 0); # ); # else ( # #set_subnode_value('v.last_sc_bytes', visitor_id, sc_bytes); # set_collected_field(visitor_id, 'last_sc_bytes', sc_bytes); # ); # # # In the database, the sc_bytes field should be the difference # sc_bytes = sc_bytes_for_db; # #); # if visitor_id #else ( # sc_bytes = 0; #); #` # requires_fields = { # sc_bytes = true # x_event = true # } # } # fix_sc_bytes # Fix the sc_stream_bytes field by subtracting this value from the previous one (it's a running total, # which otherwise will be aggregated to give too-large numbers). # fix_sc_stream_bytes = { # value = ` #sc_stream_bytes = sc_stream_bytes; # make sure sc_stream_bytes is parsed before we set it, or it might be overwritten by index/subindex parsing #if (visitor_id ne "(empty)" and visitor_id ne "-") then ( # # # If there was a previous value, use the difference in the database entry # v.last_sc_stream_bytes = get_collected_field(visitor_id, 'last_sc_stream_bytes'); # #if (subnode_exists('v.last_sc_stream_bytes', visitor_id)) then ( # if (v.last_sc_stream_bytes ne '') then ( # # # Compensates for a logging bug - seen only with cs-bytes so far. # if (sc_stream_bytes < 0) then sc_stream_bytes = v.last_sc_stream_bytes; # # #sc_stream_bytes_for_db = 0.0 + sc_stream_bytes - node_value(subnode_by_name('v.last_sc_stream_bytes', visitor_id)); # sc_stream_bytes_for_db = 0.0 + sc_stream_bytes - v.last_sc_stream_bytes; # if (sc_stream_bytes_for_db < 0) then ( # sc_stream_bytes_for_db = sc_stream_bytes; # ); # ); # else ( # # Compensates for a logging bug - seen only with cs-bytes so far. # if (sc_stream_bytes < 0) then sc_stream_bytes = 0; # sc_stream_bytes_for_db = sc_stream_bytes; # ); # # # Remember the current sc_stream_bytes value for a later event for this visitor # if (x_event eq "stop") then ( # #set_subnode_value('v.last_sc_stream_bytes', visitor_id, 0); # set_collected_field(visitor_id, 'last_sc_stream_bytes', 0); # ); # else ( # #set_subnode_value('v.last_sc_stream_bytes', visitor_id, sc_stream_bytes); # set_collected_field(visitor_id, 'last_sc_stream_bytes', sc_stream_bytes); # ); # # # In the database, the sc_stream_bytes field should be the difference # sc_stream_bytes = sc_stream_bytes_for_db; # #); # if visitor_id #else ( # sc_stream_bytes = 0; #); #` # requires_fields = { # sc_stream_bytes = true # x_event = true # } # } # fix_sc_stream_bytes # Fix the cs_stream_bytes field by subtracting this value from the previous one (it's a running total, # # which otherwise will be aggregated to give too-large numbers). # fix_cs_stream_bytes = { # value = ` #cs_stream_bytes = cs_stream_bytes; # make sure cs_stream_bytes is parsed before we set it, or it might be overwritten by index/subindex parsing #if (visitor_id ne "(empty)" and visitor_id ne "-") then ( # # # If there was a previous value, use the difference in the database entry # v.last_cs_stream_bytes = get_collected_field(visitor_id, 'last_cs_stream_bytes'); # #if (subnode_exists('v.last_cs_stream_bytes', visitor_id)) then ( # if (v.last_cs_stream_bytes ne '') then ( # # # Compensates for a logging bug - seen only with cs-bytes so far. # if (cs_stream_bytes < 0) then cs_stream_bytes = v.last_cs_stream_bytes; # # #cs_stream_bytes_for_db = 0.0 + cs_stream_bytes - node_value(subnode_by_name('v.last_cs_stream_bytes', visitor_id)); # cs_stream_bytes_for_db = 0.0 + cs_stream_bytes - v.last_cs_stream_bytes; # if (cs_stream_bytes_for_db < 0) then ( # cs_stream_bytes_for_db = cs_stream_bytes; # ); # ); # else ( # # Compensates for a logging bug - seen only with cs-bytes so far. # if (cs_stream_bytes < 0) then cs_stream_bytes = 0; # cs_stream_bytes_for_db = cs_stream_bytes; # ); # # # Remember the current cs_stream_bytes value for a later event for this visitor # if (x_event eq "unpublish") then ( # #set_subnode_value('v.last_cs_stream_bytes', visitor_id, 0); # set_collected_field(visitor_id, 'last_cs_stream_bytes', 0); # ); # else ( # #set_subnode_value('v.last_cs_stream_bytes', visitor_id, cs_stream_bytes); # set_collected_field(visitor_id, 'last_cs_stream_bytes', cs_stream_bytes); # ); # # # In the database, the cs_stream_bytes field should be the difference # cs_stream_bytes = cs_stream_bytes_for_db; # #); # if visitor_id #else ( # cs_stream_bytes = 0; #); #` # requires_fields = { # cs_stream_bytes = true # x_event = true # } # } # fix_cs_stream_bytes set_stream_duration = { value = ` if ((x_event eq "stop") and (x_category eq "stream")) then stream_duration = x_duration; ` requires_fields = { x_duration = true x_event = true x_category = true stream_duration = true } } # set_stream_duration set_session_duration = { value = ` if ((x_event eq "disconnect") and (x_category eq "session")) then session_duration = x_duration; ` requires_fields = { x_duration = true x_event = true x_category = true session_duration = true } } # set_session_duration # set x-sname to (empty) when '-' for session connect/disconnect lines # so it does not appear in the stream name report as it is only session traffic set_stream_name = { value = `if (x_sname eq '-') then x_sname = '(empty)';` requires_fields = { x_sname = true } # requires_fields } # set_stream_name } # Log.parsing_filters log.filters = { strip_port = { label = "$lang_admin.log_filters.strip_port_label" comment = "$lang_admin.log_filters.strip_port_comment" value = `if (matches_regular_expression(cs_uri_stem, '^([a-z]+://[^:]+):[0-9]+(/.*)$')) then cs_uri_stem = $1 . $2` requires_fields = { cs_uri_stem = true } # requires_fields } # strip_port 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 database.numerical_fields = { events = { default = true requires_log_field = false } visitors = { default = false requires_log_field = true log_field = "c_client_id" type = "unique" } # visitors unique_client_ips = { default = false requires_log_field = true log_field = "c_ip" type = "unique" } # unique_client_ips # sc_bytes = { # type = "int" # integer_bits = 64 # display_format_type = "bandwidth" # } # # cs_bytes = { # type = "int" # integer_bits = 64 # display_format_type = "bandwidth" # } # # sc_stream_bytes = { # type = "int" # integer_bits = 64 # display_format_type = "bandwidth" # } # # cs_stream_bytes = { # type = "int" # integer_bits = 64 # display_format_type = "bandwidth" # } # Omitted the file size and file length fields since it doesn't make sense # to aggregate these fields when the size and length are for individual streams. # 2012-09-20 - 1.2.8 - MSG - removed these as aggregating fields # x_file_size = { # type = "int" # integer_bits = 64 # display_format_type = "bandwidth" # } # x_file_length = { # type = "int" # integer_bits = 64 # display_format_type = "duration_compact" # } # KBB - 1.2 # x_duration = { # default = false # requires_log_field = false # type = "float" # display_format_type = "duration_compact" # } stream_duration = { default = false requires_log_field = false type = "int" integer_bits = 64 display_format_type = "duration_compact" } session_duration = { default = false requires_log_field = false type = "int" integer_bits = 64 display_format_type = "duration_compact" } # 2013-02-13 - GMF - Removed this field, which is perfectly worthless, since events include things like connect/disconnect/etc. Maybe could be useful if it was just "per play" # stream_duration_per_event = { # default = false # log_field = "stream_duration" # requires_log_field = true # type = "int" # integer_bits = 64 # aggregation_method = "average" # average_denominator_field = "events" # display_format_type = duration_compact # } stream_duration_per_visitor = { default = false log_field = "stream_duration" requires_log_field = true type = "int" integer_bits = 64 aggregation_method = "average" average_denominator_field = "visitors" display_format_type = duration_compact } # 2012-09-24 - GMF - Removing these because they are absolute values, and don't aggregate # x_spos = { # default = false # requires_log_field = true # aggregation_method = "average" # average_denominator_field = "events" # } # x_spos # c_spos = { # default = false # requires_log_field = true # aggregation_method = "average" # average_denominator_field = "events" # } # c_spos } # database.numerical_fields create_profile_wizard_options = { # How the reports should be grouped in the report menu report_groups = { date_time_group = { date_time = "" hour_of_day = "" day_of_week = "" tz = true } content_group = { cs_uri_stem = true cs_uri_query = true file_type = true s_uri = true x_ctx = true x_sname = true x_sname_query = true x_suri_query = true x_suri_stem = true x_suri = true x_file_ext = true x_file_name = true x_trans_sname = true x_trans_sname_query = true x_trans_file_ext = true x_page_url = true x_sid = true } # content_group client_group = { c_client_id = true c_connect_type = true c_ip = true c_proto = true c_referrer = true c_user_agent = true domain = true domain_description = true isp = true location = true organization = true screen_depth = true screen_dimensions = true } # client_group other_group = { s_ip = true x_adaptor = true x_app = true x_appinst = true x_category = true x_comment = true x_cpu_load = true x_event = true x_mem_load = true x_pid = true x_sc_qos_bytes = true x_service_name = true x_status = true x_vhost = true worms = true s_ip_prefix = true x_eid = true stream_id = true x_codec_type = true x_codec = true x_plugin = true } # other_group } # report_groups # These non-aggregating fields need to be in the database (for database filter use), but should not appear as reports. omit_reports = { cs_bytes = true sc_bytes = true cs_stream_bytes = true sc_stream_bytes = true } # omit_reports # final_step = ` # #include "templates.admin.profiles.setup_reports_util"; # #string profile = "profiles." . volatile.new_profile_name; #string reports = profile . ".statistics.reports"; #string summary = profile . ".statistics.reports.single_page_summary.report_elements"; #string menu = profile . ".statistics.reports_menu"; # ## Create the standard reports ##add_standard_reports(profile); # ## And unneeded derived reports #delete_node(reports . ".worm"); #delete_node(summary . ".worm"); #delete_node(menu . ".worm"); #` snapons = { # Attach a cumulative_field_sum snapon to compute sc_bytes sc_bytes = { snapon = "cumulative_field_sum" name = "sc_bytes_total" label = "$lang_admin.snapons.plugins.flash_media_server.sc_bytes" parameters = { date_time_field.parameter_value = "date_time" cumulative_field.parameter_value = "sc_bytes" session_id_field.parameter_value = "c_client_id" cumulative_field_sum_name = { parameter_value = "$lang_admin.snapons.plugins.flash_media_server.sc_bytes" final_node_name = "sc_bytes_total" } } # parameters requires_log_fields = { sc_bytes = true date_time = true c_client_id = true # 2011-05-23 - GMF - Can't use this field--it doesn't always exist, and if it doesn't, this snapon won't be attached, resulting in the field being summed. # x_cf_client_id = true } } # sc_bytes # Attach a cumulative_field_sum snapon to compute cs_bytes cs_bytes = { snapon = "cumulative_field_sum" name = "cs_bytes_total" label = "$lang_admin.snapons.plugins.flash_media_server.cs_bytes" parameters = { date_time_field.parameter_value = "date_time" cumulative_field.parameter_value = "cs_bytes" session_id_field.parameter_value = "c_client_id" cumulative_field_sum_name = { parameter_value = "$lang_admin.snapons.plugins.flash_media_server.cs_bytes" final_node_name = "cs_bytes_total" } } # parameters requires_log_fields = { cs_bytes = true date_time = true c_client_id = true # 2011-05-23 - GMF - Can't use this field--it doesn't always exist, and if it doesn't, this snapon won't be attached, resulting in the field being summed. # x_cf_client_id = true } } # cs_bytes # Attach a media_reports snapon media_reports = { snapon = "media_reports" name = "media_reports" label = "$lang_admin.snapons.media_reports.label" parameters = { user_field.parameter_value = "c_ip" # have_category_field.parameter_value = false # category_field.parameter_value = "category" # domain_field.parameter_value = "top_level_domain" duration_field.parameter_value = "stream_duration" stream_name_field.parameter_value = "x_sname" stream_id_field.parameter_value = "c_client_id" client_ip_field.parameter_value = "c_ip" # Don't do the default concurrent connections analysis; it's based on a single duration field, which we don't have. attach_concurrent_events.parameter_value = false } # parameters requires_database_fields = { c_ip = true stream_duration = true x_sname = true c_client_id = true } # requires_database_fields } # media_reports # Attach a concurrent_streams_wowza snapon to compute concurrent connections. concurrent_streams_wowza = { snapon = "concurrent_streams_wowza" name = "concurrent_streams_wowza" label = "$lang_admin.snapons.plugins.wowza_media_server.concurrent_streams" parameters = { date_time_field.parameter_value = "date_time" x_category_field.parameter_value = "x_category" x_event_field.parameter_value = "x_event" x_category_start_value.parameter_value = "stream" x_category_end_value.parameter_value = "stream" x_event_start_value.parameter_value = "play" x_event_end_value.parameter_value = "stop" x_event_end_value2.parameter_value = "pause" concurrent_streams_name = { parameter_value = "$lang_admin.snapons.plugins.wowza_media_server.concurrent_streams" final_node_name = "concurrent_streams" } # track_per_resource.parameter_value = true # resource_field.parameter_value = "x_sname" } # parameters requires_database_fields = { date_time = true x_category = true x_event = true } } # concurrent_streams_wowza # Add the standard reports # add_standard_reports = { # name = "add_standard_reports" # label = "add_standard_reports" # snapon = "add_standard_reports" # } # add_standard_reports } # snapons } # create_profile_wizard_options } # flash_media_server