# # Play Duration (Wowza) snapon # # This snapon calculates the play duration in a Wowza log file # play_duration_wowza = { version = "1.1.3" # 2013-03-01 - GMF - 1.0 - Initial creation # 2013-03-29 - GMF - 1.0.1 - Fixed aggregation operator (which was max rather than sum) # 2013-05-24 - GMF - 1.0.2 - Added x_event_end_value2 (e.g. unpause) # 2013-07-17 - GMF - 1.1 - Added duration=-1 to indicate when the stream is not playing, so it doesn't double-count duration when a pause is followed by a stop. # 2013-08-22 - GMF - 1.1.1 - Changed the "start" and "stop" event detection to regular expression rather than eq, so we can add additional stop events easily # 2013-09-20 - GMF - 1.1.2 - Switched from using -1, to using "notplaying" to indicate that a stream is not playing # 2013-11-27 - MSG/GMF - 1.1.3 - Added secondary sort on loadorder so all database filters can run in a single pass. label = "$lang_admin.snapons.play_duration_wowza.label" comment = "$lang_admin.snapons.play_duration_wowza.comment" config_snapon_category = "" parameters = { date_time_field = { parameter_value = "date_time" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.date_time_field.form_element_label" form_element_type = "select" select_options_source = "database_fields" description = "" } # date_time_field # This is the field which has a different value in the log data, for each session session_id_field = { parameter_value = "session_id" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.session_id.form_element_label" form_element_type = "select" select_options_source = "database_fields" description = "" } # session_id_field # This is the field which has the (cumulative) duration value duration_field = { parameter_value = "x_duration" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.duration_field.form_element_label" form_element_type = "select" select_options_source = "database_fields" description = "" } # duration_field x_category_field = { parameter_value = "x_category" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_category_field.form_element_label" form_element_type = "select" select_options_source = "database_fields" description = "" } # x_category_field x_event_field = { parameter_value = "x_event" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_event_field.form_element_label" form_element_type = "select" select_options_source = "database_fields" description = "" } # x_event_field x_category_start_value = { parameter_value = "stream" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_category_start_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_category_start_value x_category_end_value = { parameter_value = "stream" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_category_end_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_category_end_value x_category_end_value = { parameter_value = "stream" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_category_end_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_category_end_value x_event_start_value = { parameter_value = "create" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_event_start_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_event_start_value x_event_start_value2 = { parameter_value = "create" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_event_start_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_event_start_value2 x_event_end_value = { parameter_value = "destroy" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_event_end_value.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_event_end_value x_event_end_value2 = { parameter_value = "destroy" validation_type = "string" form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.x_event_end_value2.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # x_event_end_value2 play_duration_name = { parameter_value = "Play duration" # LM final_node_name = "play_duration" validation_type = "field_label" validate_field_label_for = { database_fields = true report_fields = true } form_element_label = "$lang_admin.snapons.play_duration_wowza.parameters.play_duration_name.form_element_label" form_element_type = "text" form_element_width = "380" description = "" } # play_duration_name } # parameters parameters_form = { group_1 = { description = "$lang_admin.snapons.play_duration_wowza.parameters_form.group_1.description" parameters = { date_time_field = true duration_field = true session_id_field = true x_category_field = true x_event_field = true } # parameters } # group 1 group_2 = { description = "$lang_admin.snapons.play_duration_wowza.parameters_form.group_2.description" parameters = { x_category_start_value = true x_category_end_value = true x_event_start_value = true x_event_start_value2 = true x_event_end_value = true x_event_end_value2 = true play_duration_name = true } # parameters } # group 2 } # parameters_form attach_operations = { # When attaching: Add the concurrent events database fields add_database_field = { type = "add_database_fields" fields = { "{= @parameters{'play_duration_name'}{'final_node_name'} =}" = { label = "{= @parameters{'play_duration_name'}{'parameter_value'} =}" type = "int" derivation_method = "database_filter" aggregation_method = "sum" category = "" index = "true" suppress_top = "0" suppress_bottom = "2" integer_bits = "0" } # play_duration_name } # fields } # add_database_field # When attaching: add the database filter to calculate the field add_database_filter = { type = "add_database_filters" filters = { "{= @parameters{'play_duration_name'}{'final_node_name'} =}" = { conditions = { # Sort chronologically sort = { type = "sort" fields = { date_time = { column_name = "{= @parameters{'date_time_field'}{'parameter_value'} =}" } loadorder = { column_name = "loadorder" } } # fields } # sort } # conditions # The follow expression is the code which implements the filter action expression = ` #echo("[" . {= @parameters{'session_id_field'}{'parameter_value'} =} . "] {= @parameters{'x_category_field'}{'parameter_value'} =}: " . {= @parameters{'x_category_field'}{'parameter_value'} =} . "; {= @parameters{'x_event_field'}{'parameter_value'} =}=" . {= @parameters{'x_event_field'}{'parameter_value'} =} . "; {= @parameters{'duration_field'}{'parameter_value'} =}=" . {= @parameters{'duration_field'}{'parameter_value'} =}); if (({= @parameters{'x_category_field'}{'parameter_value'} =} eq "{= @parameters{'x_category_start_value'}{'parameter_value'} =}") and (matches_regular_expression({= @parameters{'x_event_field'}{'parameter_value'} =}, "{= @parameters{'x_event_start_value'}{'parameter_value'} =}") or matches_regular_expression({= @parameters{'x_event_field'}{'parameter_value'} =}, "{= @parameters{'x_event_start_value2'}{'parameter_value'} =}"))) then ( #echo("play detected; {= @parameters{'session_id_field'}{'parameter_value'} =}=" . {= @parameters{'session_id_field'}{'parameter_value'} =} . "; {= @parameters{'duration_field'}{'parameter_value'} =}=" . {= @parameters{'duration_field'}{'parameter_value'} =}); set_collected_field({= @parameters{'session_id_field'}{'parameter_value'} =}, '{= @parameters{'duration_field'}{'parameter_value'} =}', {= @parameters{'duration_field'}{'parameter_value'} =}); ); else if (({= @parameters{'x_category_field'}{'parameter_value'} =} eq "{= @parameters{'x_category_end_value'}{'parameter_value'} =}") and (matches_regular_expression({= @parameters{'x_event_field'}{'parameter_value'} =}, "{= @parameters{'x_event_end_value'}{'parameter_value'} =}") or matches_regular_expression({= @parameters{'x_event_field'}{'parameter_value'} =}, "{= @parameters{'x_event_end_value2'}{'parameter_value'} =}"))) then ( #echo({= @parameters{'x_event_field'}{'parameter_value'} =} . " detected; {= @parameters{'session_id_field'}{'parameter_value'} =}=" . {= @parameters{'session_id_field'}{'parameter_value'} =} . "; {= @parameters{'duration_field'}{'parameter_value'} =}=" . {= @parameters{'duration_field'}{'parameter_value'} =}); # If the stream is playing ({= @parameters{'duration_field'}{'parameter_value'} =} isn't "notplaying"), compute the duration by subtracting the event that started to play. if (get_collected_field({= @parameters{'session_id_field'}{'parameter_value'} =}, '{= @parameters{'duration_field'}{'parameter_value'} =}') ne "notplaying") then {= @parameters{'play_duration_name'}{'final_node_name'} =} = {= @parameters{'duration_field'}{'parameter_value'} =} - get_collected_field({= @parameters{'session_id_field'}{'parameter_value'} =}, '{= @parameters{'duration_field'}{'parameter_value'} =}'); # Set {= @parameters{'duration_field'}{'parameter_value'} =} to "notplaying" to indicate that the stream is not now playing. set_collected_field({= @parameters{'session_id_field'}{'parameter_value'} =}, '{= @parameters{'duration_field'}{'parameter_value'} =}', "notplaying"); ); #echo(" -> {= @parameters{'play_duration_name'}{'final_node_name'} =}=" . {= @parameters{'play_duration_name'}{'final_node_name'} =}); ` } # play_duration_name } # filters } # add_database_filter # When attaching: Add the report field add_report_field = { type = "add_report_fields" fields = { "{= @parameters{'play_duration_name'}{'final_node_name'} =}" = { label = "{= @parameters{'play_duration_name'}{'parameter_value'} =}" column_label = "" column_info = "" database_field = "{= @parameters{'play_duration_name'}{'final_node_name'} =}" display_format_type = "integer" show_remainder_value = true show_average_value = true show_min_value = true show_max_value = true show_total_value = true percent_calculation = "sum" display_format_type = "duration_compact" } # play_duration_name } # fields } # add_report_field # When attaching: Add the report field to all xref groups add_xref_field = { type = "add_xref_fields" xref_group = "*" fields = { "{= @parameters{'play_duration_name'}{'final_node_name'} =}" = "" } # fields } # add_xref_field # When attaching: Add the column to all report elements add_report_columns = { type = "add_report_element_columns" report = "*" report_element = "*" columns = { "{= @parameters{'play_duration_name'}{'final_node_name'} =}" = { report_field = "{= @parameters{'play_duration_name'}{'final_node_name'} =}" show_column = true show_percent_column = false show_bar_column = false show_graph = false } # {= @parameters{'play_duration_name'}{'final_node_name'} =} } # columns } # add_report_columns } # attach_operations } # play_duration_wowza