From 7c8e5ca733c0da344d9866fca94388018aa2ca91 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 5 Sep 2023 17:02:04 +0300 Subject: [PATCH 01/46] update dashboard workflow --- .github/workflows/update_dashboard.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index 6beeadd62..31015dc36 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -33,12 +33,14 @@ jobs: uses: docker/metadata-action@v4 with: images: ghcr.io/${{ github.repository }}/superset_df_dashboard + flavor: | + latest=auto tags: | - type=ref,event=branch - type=semver,event={{version}} + type=ref,event=tag + type=raw,value=latest,enable={{is_default_branch}} - name: Build and upload image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v4 with: file: dff/utils/docker/dockerfile_stats tags: ${{ steps.meta.outputs.tags }} From bbd2b3d9d8e2c3f52d7d2b5a3aa1899418b262cf Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 6 Sep 2023 14:02:31 +0300 Subject: [PATCH 02/46] run on workflow_dispatch --- .github/workflows/update_dashboard.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index 31015dc36..8503b8af5 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -7,6 +7,7 @@ on: paths: - 'dff/utils/docker/dockerfile_stats' - 'dff/utils/docker/entrypoint_stats.sh' + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 67128981809248bf04d0006f114cd86a3c34d716 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 7 Sep 2023 13:48:15 +0300 Subject: [PATCH 03/46] trigger on PR to dev for debugging --- .github/workflows/update_dashboard.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index 8503b8af5..ae9b896f7 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -1,6 +1,9 @@ name: update_dashboard on: + pull_request: + branches: + - dev push: branches: - 'dev' From 941a581823ee77ac2eb60434659c58fd649509da Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 7 Sep 2023 14:00:19 +0300 Subject: [PATCH 04/46] update build push action --- .github/workflows/update_dashboard.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index ae9b896f7..dcff09e98 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -46,6 +46,7 @@ jobs: - name: Build and upload image uses: docker/build-push-action@v4 with: - file: dff/utils/docker/dockerfile_stats + context: dff/utils/docker + file: dockerfile_stats tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file From 5d7c7535308e0fee2709873a32968774fb37b0aa Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 7 Sep 2023 14:05:57 +0300 Subject: [PATCH 05/46] update context && file --- .github/workflows/update_dashboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index dcff09e98..b2a11e313 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -47,6 +47,6 @@ jobs: uses: docker/build-push-action@v4 with: context: dff/utils/docker - file: dockerfile_stats + file: dff/utils/docker/dockerfile_stats tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file From eaf772a5003efcf25ac3cece29c5430fdcf1df74 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 7 Sep 2023 14:22:48 +0300 Subject: [PATCH 06/46] remove trigger on PR --- .github/workflows/update_dashboard.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index b2a11e313..687ea5e7d 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -1,9 +1,6 @@ name: update_dashboard on: - pull_request: - branches: - - dev push: branches: - 'dev' From 27170eab30086b3732954c9785153b15b3e20e31 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 12 Sep 2023 12:42:03 +0300 Subject: [PATCH 07/46] add sample data provider --- tutorials/stats/3_sample_data_provider.py | 205 ++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 tutorials/stats/3_sample_data_provider.py diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py new file mode 100644 index 000000000..2dd4bb76c --- /dev/null +++ b/tutorials/stats/3_sample_data_provider.py @@ -0,0 +1,205 @@ +import random +import asyncio +from tqdm import tqdm +from dff.script import RESPONSE, TRANSITIONS, Context, Message +from dff.script import conditions as cnd +from dff.pipeline import Pipeline, Service, ACTOR +from dff.stats import ( + default_extractors, + OtelInstrumentor, +) + +dff_instrumentor = OtelInstrumentor.from_url("grpc://localhost:4317", insecure=True) +dff_instrumentor.instrument() + +transitions = { + "root": { + "start": [ + "hi", + "i like animals", + "let's talk about animals", + ] + }, + "animals": { + "have_pets": ["yes"], + "like_animals": ["yes"], + "what_animal": ["bird", "dog"], + "ask_about_breed": ["pereat", "bulldog", "i do not known"], + }, + "news": { + "what_news": ["science", "sport"], + "ask_about_science": ["yes", "let's change the topic"], + "science_news": ["ok", "let's change the topic"], + "ask_about_sport": ["yes", "let's change the topic"], + "sport_news": ["ok", "let's change the topic"], + }, + "small_talk": { + "ask_some_questions": [ + "fine", + "let's talk about animals", + "let's talk about news", + ], + "ask_talk_about": ["dog", "let's talk about news"], + }, +} +# a dialog script +script = { + "root": { + "start": { + RESPONSE: Message(text="Hi"), + TRANSITIONS: { + ("small_talk", "ask_some_questions"): cnd.exact_match(Message(text="hi")), + ("animals", "have_pets"): cnd.exact_match(Message(text="i like animals")), + ("animals", "like_animals"): cnd.exact_match( + Message(text="let's talk about animals") + ), + ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), + }, + }, + "fallback": {RESPONSE: Message(text="Oops")}, + }, + "animals": { + "have_pets": { + RESPONSE: Message(text="do you have pets?"), + TRANSITIONS: {"what_animal": cnd.exact_match(Message(text="yes"))}, + }, + "like_animals": { + RESPONSE: Message(text="do you like it?"), + TRANSITIONS: {"what_animal": cnd.exact_match(Message(text="yes"))}, + }, + "what_animal": { + RESPONSE: Message(text="what animals do you have?"), + TRANSITIONS: { + "ask_about_color": cnd.exact_match(Message(text="bird")), + "ask_about_breed": cnd.exact_match(Message(text="dog")), + }, + }, + "ask_about_color": {RESPONSE: Message(text="what color is it")}, + "ask_about_breed": { + RESPONSE: Message(text="what is this breed?"), + TRANSITIONS: { + "ask_about_breed": cnd.exact_match(Message(text="pereat")), + "tell_fact_about_breed": cnd.exact_match(Message(text="bulldog")), + "ask_about_training": cnd.exact_match(Message(text="i do not known")), + }, + }, + "tell_fact_about_breed": { + RESPONSE: Message( + text="Bulldogs appeared in England as specialized bull-baiting dogs. " + ), + }, + "ask_about_training": {RESPONSE: Message(text="Do you train your dog? ")}, + }, + "news": { + "what_news": { + RESPONSE: Message(text="what kind of news do you prefer?"), + TRANSITIONS: { + "ask_about_science": cnd.exact_match(Message(text="science")), + "ask_about_sport": cnd.exact_match(Message(text="sport")), + }, + }, + "ask_about_science": { + RESPONSE: Message(text="i got news about science, do you want to hear?"), + TRANSITIONS: { + "science_news": cnd.exact_match(Message(text="yes")), + ("small_talk", "ask_some_questions"): cnd.exact_match( + Message(text="let's change the topic") + ), + }, + }, + "science_news": { + RESPONSE: Message(text="This is science news"), + TRANSITIONS: { + "what_news": cnd.exact_match(Message(text="ok")), + ("small_talk", "ask_some_questions"): cnd.exact_match( + Message(text="let's change the topic") + ), + }, + }, + "ask_about_sport": { + RESPONSE: Message(text="i got news about sport, do you want to hear?"), + TRANSITIONS: { + "sport_news": cnd.exact_match(Message(text="yes")), + ("small_talk", "ask_some_questions"): cnd.exact_match( + Message(text="let's change the topic") + ), + }, + }, + "sport_news": { + RESPONSE: Message(text="This is sport news"), + TRANSITIONS: { + "what_news": cnd.exact_match(Message(text="ok")), + ("small_talk", "ask_some_questions"): cnd.exact_match( + Message(text="let's change the topic") + ), + }, + }, + }, + "small_talk": { + "ask_some_questions": { + RESPONSE: Message(text="how are you"), + TRANSITIONS: { + "ask_talk_about": cnd.exact_match(Message(text="fine")), + ("animals", "like_animals"): cnd.exact_match( + Message(text="let's talk about animals") + ), + ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), + }, + }, + "ask_talk_about": { + RESPONSE: Message(text="what do you want to talk about"), + TRANSITIONS: { + ("animals", "like_animals"): cnd.exact_match(Message(text="dog")), + ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), + }, + }, + }, +} + +pipeline = Pipeline.from_dict( + { + "script": script, + "start_label": ("root", "start"), + "fallback_label": ("root", "fallback"), + "components": [ + Service( + handler=ACTOR, + before_handler=[default_extractors.get_timing_before], + after_handler=[ + default_extractors.get_timing_after, + default_extractors.get_current_label, + ], + ), + ], + } +) + + +async def worker(queue: asyncio.Queue): + ctx: Context = await queue.get() + label = ctx.last_label if ctx.last_label else pipeline.actor.fallback_label + flow, node = label[:2] + if [flow, node] == ["root", "fallback"]: + ctx = Context() + flow, node = ["root", "start"] + answers = list(transitions.get(flow, {}).get(node, [])) + in_text = random.choice(answers) if answers else "go to fallback" + in_message = Message(text=in_text) + rand_interval = float(random.randint(0, 1)) + random.random() + await asyncio.sleep(rand_interval) + ctx = await pipeline._run_pipeline(in_message, ctx.id) + rand_interval = float(random.randint(0, 1)) + random.random() + await asyncio.sleep(rand_interval) + await queue.put(ctx) + + +async def main(n_iterations: int = 25): + ctxs = asyncio.Queue() + for _ in range(4): + await ctxs.put(Context()) + for _ in tqdm(range(n_iterations)): + await asyncio.gather(*(worker(ctxs) for _ in range(4))) + + +if __name__ == "__main__": + asyncio.run(main()) From 0531c4996a849c318a05c074beb60cb7e8a5d548 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 14 Sep 2023 15:58:26 +0300 Subject: [PATCH 08/46] Update dashboard, finalize data provider --- .../Current_topic_slot_bar_chart_16.yaml | 71 + ...urrent_topic_time_series_bar_chart_15.yaml | 85 ++ .../charts/Flow_visit_ratio_monitor_1.yaml | 78 -- .../charts/Flow_visit_ratio_monitor_13.yaml | 101 ++ .../charts/Node_Visits_2.yaml | 59 - .../charts/Node_Visits_6.yaml | 89 ++ .../charts/Node_counts_3.yaml | 59 - .../charts/Node_counts_9.yaml | 87 ++ .../charts/Node_visit_ratio_monitor_2.yaml | 109 ++ .../charts/Node_visit_ratio_monitor_4.yaml | 86 -- .../charts/Node_visits_cloud_5.yaml | 48 - .../charts/Node_visits_ratio_3.yaml | 91 ++ .../charts/Node_visits_ratio_6.yaml | 65 - .../charts/Node_visits_sunburst_10.yaml | 76 ++ .../charts/Node_visits_sunburst_7.yaml | 69 - .../charts/Rating_slot_line_chart_17.yaml | 92 ++ .../Service_load_max_dialogue_length_8.yaml | 83 -- ...users_9.yaml => Service_load_users_4.yaml} | 0 .../superset_dashboard/charts/Table_10.yaml | 34 - .../superset_dashboard/charts/Table_14.yaml | 36 + ..._labels_11.yaml => Terminal_labels_7.yaml} | 0 .../charts/Transition_counts_1.yaml | 101 ++ .../charts/Transition_counts_12.yaml | 63 - .../charts/Transition_layout_13.yaml | 62 - .../charts/Transition_layout_8.yaml | 101 ++ .../charts/Transition_ratio_chord_12.yaml | 86 ++ .../charts/Transition_ratio_chord_14.yaml | 48 - .../dashboards/DFF_Stats_1.yaml | 555 -------- .../DFF_statistics_dashboard_1.yaml | 1211 +++++++++++++++++ .../datasets/dff_database/dff_node_stats.yaml | 15 +- dff/config/superset_dashboard/metadata.yaml | 2 +- dff/stats/instrumentor.py | 2 +- dff/utils/testing/toy_script.py | 140 ++ tests/stats/test_main.py | 11 +- tutorials/stats/3_sample_data_provider.py | 223 +-- 35 files changed, 2562 insertions(+), 1476 deletions(-) create mode 100644 dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml create mode 100644 dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml delete mode 100644 dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_1.yaml create mode 100644 dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_Visits_2.yaml create mode 100644 dff/config/superset_dashboard/charts/Node_Visits_6.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_counts_3.yaml create mode 100644 dff/config/superset_dashboard/charts/Node_counts_9.yaml create mode 100644 dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_4.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_visits_cloud_5.yaml create mode 100644 dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml create mode 100644 dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml delete mode 100644 dff/config/superset_dashboard/charts/Node_visits_sunburst_7.yaml create mode 100644 dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml delete mode 100644 dff/config/superset_dashboard/charts/Service_load_max_dialogue_length_8.yaml rename dff/config/superset_dashboard/charts/{Service_load_users_9.yaml => Service_load_users_4.yaml} (100%) delete mode 100644 dff/config/superset_dashboard/charts/Table_10.yaml create mode 100644 dff/config/superset_dashboard/charts/Table_14.yaml rename dff/config/superset_dashboard/charts/{Terminal_labels_11.yaml => Terminal_labels_7.yaml} (100%) create mode 100644 dff/config/superset_dashboard/charts/Transition_counts_1.yaml delete mode 100644 dff/config/superset_dashboard/charts/Transition_counts_12.yaml delete mode 100644 dff/config/superset_dashboard/charts/Transition_layout_13.yaml create mode 100644 dff/config/superset_dashboard/charts/Transition_layout_8.yaml create mode 100644 dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml delete mode 100644 dff/config/superset_dashboard/charts/Transition_ratio_chord_14.yaml delete mode 100644 dff/config/superset_dashboard/dashboards/DFF_Stats_1.yaml create mode 100644 dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml diff --git a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml new file mode 100644 index 000000000..028bbe494 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml @@ -0,0 +1,71 @@ +slice_name: Current topic slot [bar chart] +description: null +certified_by: null +certification_details: null +viz_type: dist_bar +params: + datasource: 2__table + viz_type: dist_bar + slice_id: 16 + granularity_sqla: start_time + time_range: No filter + metrics: + - count + adhoc_filters: + - clause: WHERE + comparator: get_slots + datasourceWarning: false + expressionType: SIMPLE + filterOptionName: filter_sz14lhn7d1d_c0zqn5dpgk + isExtra: false + isNew: false + operator: == + operatorId: EQUALS + sqlExpression: null + subject: data_key + - clause: WHERE + comparator: null + datasourceWarning: false + expressionType: SQL + filterOptionName: filter_945dhn41x2m_sci7gkxy7o + isExtra: false + isNew: false + operator: null + sqlExpression: JSON_VALUE(data, '$.current_topic') <> '' + subject: null + groupby: + - expressionType: SQL + label: My column + sqlExpression: JSON_VALUE(data, '$.current_topic') + columns: + - request_id + row_limit: 10000 + order_desc: true + color_scheme: echarts4Colors + show_legend: true + rich_tooltip: true + bar_stacked: true + order_bars: false + y_axis_format: SMART_NUMBER + y_axis_label: Counts + y_axis_bounds: + - null + - null + x_axis_label: Topic slot values + bottom_margin: auto + x_ticks_layout: auto + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"having":"","where":"(JSON_VALUE(data, + ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":[{"expressionType":"SQL","label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')"},"request_id"],"metrics":["count"],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":16,"granularity_sqla":"start_time","time_range":"No + filter","metrics":["count"],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_sz14lhn7d1d_c0zqn5dpgk","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_945dhn41x2m_sci7gkxy7o","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, + ''$.current_topic'') <> ''''","subject":null}],"groupby":[{"expressionType":"SQL","label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')"}],"columns":["request_id"],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":false,"y_axis_format":"SMART_NUMBER","y_axis_label":"Counts","y_axis_bounds":[null,null],"x_axis_label":"Topic + slot values","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: a70c05d0-770b-4068-a55d-934283f5b1bb +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml b/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml new file mode 100644 index 000000000..6d34316be --- /dev/null +++ b/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml @@ -0,0 +1,85 @@ +slice_name: Current topic [time series bar chart] +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_bar +params: + datasource: 2__table + viz_type: echarts_timeseries_bar + slice_id: 15 + granularity_sqla: start_time + time_grain_sqla: PT1M + time_range: No filter + metrics: + - count + groupby: + - expressionType: SQL + label: context_id + sqlExpression: JSON_VALUE(data, '$.current_topic') + adhoc_filters: + - clause: WHERE + comparator: get_slots + datasourceWarning: false + expressionType: SIMPLE + filterOptionName: filter_8tft5fr07ea_urtdezftgn + isExtra: false + isNew: false + operator: == + operatorId: EQUALS + sqlExpression: null + subject: data_key + - clause: WHERE + comparator: null + datasourceWarning: false + expressionType: SQL + filterOptionName: filter_4ffdpny1zzm_vmlo11yw7i + isExtra: false + isNew: false + operator: null + sqlExpression: JSON_VALUE(data, '$.current_topic') <> '' + subject: null + order_desc: true + row_limit: 10000 + truncate_metric: true + show_empty_columns: true + comparison_type: values + annotation_layers: [] + forecastPeriods: 10 + forecastInterval: 0.8 + orientation: vertical + x_axis_title: Time axis + x_axis_title_margin: 30 + y_axis_title: Value counts over time + y_axis_title_margin: 30 + y_axis_title_position: Left + color_scheme: echarts4Colors + show_value: false + stack: true + only_total: true + show_legend: true + legendType: scroll + legendOrientation: top + x_axis_time_format: smart_date + y_axis_format: SMART_NUMBER + y_axis_bounds: + - null + - null + rich_tooltip: true + tooltipSortByMetric: true + tooltipTimeFormat: smart_date + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(JSON_VALUE(data, + ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'')"}],"metrics":["count"],"orderby":[["count",false]],"annotation_layers":[],"row_limit":10000,"series_columns":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'')"}],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["context_id"],"aggregates":{"count":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"count":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":15,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No + filter","metrics":["count"],"groupby":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'')"}],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_8tft5fr07ea_urtdezftgn","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_4ffdpny1zzm_vmlo11yw7i","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, + ''$.current_topic'') <> ''''","subject":null}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title":"Time + axis","x_axis_title_margin":30,"y_axis_title":"Value counts over time","y_axis_title_margin":30,"y_axis_title_position":"Left","color_scheme":"echarts4Colors","show_value":false,"stack":true,"only_total":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipSortByMetric":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: f8215b4d-cdaf-489a-90b2-040da840ab35 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_1.yaml b/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_1.yaml deleted file mode 100644 index 4fb4c2124..000000000 --- a/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_1.yaml +++ /dev/null @@ -1,78 +0,0 @@ -slice_name: Flow visit ratio monitor -description: null -certified_by: null -certification_details: null -viz_type: echarts_timeseries_bar -params: - datasource: 2__table - viz_type: echarts_timeseries_bar - slice_id: 1 - granularity_sqla: start_time - time_grain_sqla: null - time_range: No filter - metrics: - - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_waxxrrnkwwm_zudaex5z8bh - sqlExpression: null - groupby: - - flow_label - contributionMode: column - adhoc_filters: [] - order_desc: true - row_limit: 10000 - truncate_metric: true - show_empty_columns: true - comparison_type: values - annotation_layers: [] - forecastPeriods: 10 - forecastInterval: 0.8 - orientation: vertical - x_axis_title_margin: 15 - y_axis_title: '' - y_axis_title_margin: 50 - y_axis_title_position: Left - color_scheme: supersetColors - stack: true - only_total: true - zoomable: true - show_legend: true - legendType: scroll - legendOrientation: top - x_axis_time_format: smart_date - y_axis_format: SMART_NUMBER - y_axis_bounds: - - null - - null - rich_tooltip: true - tooltipTimeFormat: smart_date - extra_form_data: {} - dashboards: - - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":["flow_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["flow_label"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["flow_label"],"aggregates":{"COUNT(context_id)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(context_id)":null},"level":0,"inplace":true}},{"operation":"contribution","options":{"orientation":"column"}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":1,"granularity_sqla":"start_time","time_grain_sqla":null,"time_range":"No - filter","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null}],"groupby":["flow_label"],"contributionMode":"column","adhoc_filters":[],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title_margin":15,"y_axis_title":"","y_axis_title_margin":50,"y_axis_title_position":"Left","color_scheme":"supersetColors","stack":true,"only_total":true,"zoomable":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' -cache_timeout: null -uuid: ba02528b-184b-4304-b027-f2b7d9011ab0 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml b/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml new file mode 100644 index 000000000..633362e20 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml @@ -0,0 +1,101 @@ +slice_name: Flow visit ratio monitor +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_bar +params: + datasource: 2__table + viz_type: echarts_timeseries_bar + slice_id: 13 + granularity_sqla: start_time + time_grain_sqla: PT1M + time_range: 'DATEADD(DATETIME("now"), -1, day) : now' + metrics: + - aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_waxxrrnkwwm_zudaex5z8bh + sqlExpression: null + groupby: + - flow_label + contributionMode: column + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_xqjhabd7z8p_05dlj2lmg6ue + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_822k33tkrei_irkb2zdjds + order_desc: true + row_limit: 10000 + truncate_metric: true + show_empty_columns: true + comparison_type: values + annotation_layers: [] + forecastPeriods: 10 + forecastInterval: 0.8 + orientation: vertical + x_axis_title_margin: 15 + y_axis_title: '' + y_axis_title_margin: 50 + y_axis_title_position: Left + color_scheme: echarts4Colors + stack: true + only_total: true + zoomable: true + show_legend: true + legendType: scroll + legendOrientation: top + x_axis_time_format: smart_date + y_axis_format: SMART_NUMBER + y_axis_bounds: + - null + - null + rich_tooltip: true + tooltipTimeFormat: smart_date + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"DATEADD(DATETIME(\"now\"), + -1, day) : now","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["flow_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["flow_label"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["flow_label"],"aggregates":{"COUNT(context_id)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(context_id)":null},"level":0,"inplace":true}},{"operation":"contribution","options":{"orientation":"column"}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":13,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"DATEADD(DATETIME(\"now\"), + -1, day) : now","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_waxxrrnkwwm_zudaex5z8bh","sqlExpression":null}],"groupby":["flow_label"],"contributionMode":"column","adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_xqjhabd7z8p_05dlj2lmg6ue"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_822k33tkrei_irkb2zdjds"}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title_margin":15,"y_axis_title":"","y_axis_title_margin":50,"y_axis_title_position":"Left","color_scheme":"echarts4Colors","stack":true,"only_total":true,"zoomable":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: ba02528b-184b-4304-b027-f2b7d9011ab0 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_Visits_2.yaml b/dff/config/superset_dashboard/charts/Node_Visits_2.yaml deleted file mode 100644 index 802288e28..000000000 --- a/dff/config/superset_dashboard/charts/Node_Visits_2.yaml +++ /dev/null @@ -1,59 +0,0 @@ -slice_name: Node Visits -description: null -certified_by: null -certification_details: null -viz_type: dist_bar -params: - adhoc_filters: [] - bottom_margin: auto - color_scheme: supersetColors - columns: - - label - datasource: 3__table - extra_form_data: {} - granularity_sqla: start_time - groupby: - - request_id - metrics: - - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 20 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_l2mle87zvnb_nfqzdxmig1d - sqlExpression: null - order_desc: true - rich_tooltip: true - row_limit: 10000 - show_legend: true - time_range: No filter - viz_type: dist_bar - x_axis_label: History id - x_ticks_layout: auto - y_axis_bounds: - - null - - null - y_axis_format: SMART_NUMBER - y_axis_label: Node visits -query_context: null -cache_timeout: null -uuid: 44f4ab9d-5072-4926-a6ed-8615fb81b3d0 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_Visits_6.yaml b/dff/config/superset_dashboard/charts/Node_Visits_6.yaml new file mode 100644 index 000000000..a0485c738 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Node_Visits_6.yaml @@ -0,0 +1,89 @@ +slice_name: Node Visits +description: null +certified_by: null +certification_details: null +viz_type: dist_bar +params: + datasource: 2__table + viz_type: dist_bar + slice_id: 6 + granularity_sqla: start_time + time_range: No filter + metrics: + - aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 20 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_l2mle87zvnb_nfqzdxmig1d + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_jejo4gd8be_f4ygcxhh98w + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_wa9z5rxxr2_b9ez0nkk5le + groupby: + - request_id + columns: + - label + row_limit: 10000 + order_desc: true + color_scheme: echarts4Colors + show_legend: true + rich_tooltip: true + bar_stacked: true + y_axis_format: SMART_NUMBER + y_axis_label: Node visits + y_axis_bounds: + - null + - null + x_axis_label: Dialog turn + bottom_margin: auto + x_ticks_layout: auto + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["request_id","label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":20,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_l2mle87zvnb_nfqzdxmig1d","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":6,"granularity_sqla":"start_time","time_range":"No + filter","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":20,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_l2mle87zvnb_nfqzdxmig1d","sqlExpression":null}],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_jejo4gd8be_f4ygcxhh98w"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_wa9z5rxxr2_b9ez0nkk5le"}],"groupby":["request_id"],"columns":["label"],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"y_axis_format":"SMART_NUMBER","y_axis_label":"Node + visits","y_axis_bounds":[null,null],"x_axis_label":"Dialog turn","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 44f4ab9d-5072-4926-a6ed-8615fb81b3d0 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_counts_3.yaml b/dff/config/superset_dashboard/charts/Node_counts_3.yaml deleted file mode 100644 index 8cf476c2f..000000000 --- a/dff/config/superset_dashboard/charts/Node_counts_3.yaml +++ /dev/null @@ -1,59 +0,0 @@ -slice_name: Node counts -description: null -certified_by: null -certification_details: null -viz_type: dist_bar -params: - adhoc_filters: [] - bar_stacked: true - bottom_margin: auto - color_scheme: supersetColors - columns: - - flow_label - datasource: 1__table - extra_form_data: {} - granularity_sqla: start_time - groupby: - - label - metrics: - - aggregate: COUNT_DISTINCT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT_DISTINCT(context_id) - optionName: metric_axee7fzlpu_upud0bdjv6 - sqlExpression: null - order_bars: true - order_desc: true - rich_tooltip: true - row_limit: 10000 - show_legend: true - time_range: No filter - viz_type: dist_bar - x_ticks_layout: auto - y_axis_bounds: - - null - - null - y_axis_format: SMART_NUMBER -query_context: null -cache_timeout: null -uuid: 0c47c7b5-f500-46cb-97e3-9ebb637f0c8a -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_counts_9.yaml b/dff/config/superset_dashboard/charts/Node_counts_9.yaml new file mode 100644 index 000000000..5d568c3de --- /dev/null +++ b/dff/config/superset_dashboard/charts/Node_counts_9.yaml @@ -0,0 +1,87 @@ +slice_name: Node counts +description: null +certified_by: null +certification_details: null +viz_type: dist_bar +params: + datasource: 2__table + viz_type: dist_bar + slice_id: 9 + granularity_sqla: start_time + time_range: No filter + metrics: + - aggregate: COUNT_DISTINCT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT_DISTINCT(context_id) + optionName: metric_axee7fzlpu_upud0bdjv6 + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_vhz5xz5fww_dgbx6adq7e + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_s3zhicnn9x_9xljjdrli2 + groupby: + - label + columns: + - flow_label + row_limit: 10000 + order_desc: true + color_scheme: echarts4Colors + show_legend: true + rich_tooltip: true + bar_stacked: true + order_bars: true + y_axis_format: SMART_NUMBER + y_axis_bounds: + - null + - null + bottom_margin: auto + x_ticks_layout: auto + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["label","flow_label"],"metrics":[{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_axee7fzlpu_upud0bdjv6","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":9,"granularity_sqla":"start_time","time_range":"No + filter","metrics":[{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_axee7fzlpu_upud0bdjv6","sqlExpression":null}],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_vhz5xz5fww_dgbx6adq7e"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_s3zhicnn9x_9xljjdrli2"}],"groupby":["label"],"columns":["flow_label"],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":true,"y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 0c47c7b5-f500-46cb-97e3-9ebb637f0c8a +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml new file mode 100644 index 000000000..a733c5dc1 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml @@ -0,0 +1,109 @@ +slice_name: Node visit ratio monitor +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_bar +params: + datasource: 2__table + viz_type: echarts_timeseries_bar + slice_id: 2 + granularity_sqla: start_time + time_grain_sqla: PT1M + time_range: 'DATEADD(DATETIME("now"), -1, day) : now' + metrics: + - aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_9yefk3wj2g_5wbp61n0pyr + sqlExpression: null + groupby: + - flow_label + - node_label + contributionMode: column + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_y0hyd1ebac9_flmblpn0ymt + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_tjpviv3vvq_fdqstvdz39m + order_desc: true + row_limit: 10000 + truncate_metric: true + show_empty_columns: true + comparison_type: values + annotation_layers: [] + forecastPeriods: 10 + forecastInterval: 0.8 + orientation: vertical + x_axis_title: Datetime + x_axis_title_margin: 30 + y_axis_title: Node visit ratio + y_axis_title_margin: 50 + y_axis_title_position: Left + color_scheme: echarts4Colors + stack: true + only_total: true + zoomable: true + show_legend: true + legendType: scroll + legendOrientation: top + x_axis_time_format: smart_date + xAxisLabelRotation: 45 + y_axis_format: SMART_NUMBER + logAxis: false + minorSplitLine: false + truncateYAxis: false + y_axis_bounds: + - null + - null + rich_tooltip: true + tooltipSortByMetric: true + tooltipTimeFormat: smart_date + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"DATEADD(DATETIME(\"now\"), + -1, day) : now","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["flow_label","node_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["flow_label","node_label"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["flow_label","node_label"],"aggregates":{"COUNT(context_id)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(context_id)":null},"level":0,"inplace":true}},{"operation":"contribution","options":{"orientation":"column"}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":2,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"DATEADD(DATETIME(\"now\"), + -1, day) : now","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null}],"groupby":["flow_label","node_label"],"contributionMode":"column","adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_y0hyd1ebac9_flmblpn0ymt"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_tjpviv3vvq_fdqstvdz39m"}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title":"Datetime","x_axis_title_margin":30,"y_axis_title":"Node + visit ratio","y_axis_title_margin":50,"y_axis_title_position":"Left","color_scheme":"echarts4Colors","stack":true,"only_total":true,"zoomable":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","xAxisLabelRotation":45,"y_axis_format":"SMART_NUMBER","logAxis":false,"minorSplitLine":false,"truncateYAxis":false,"y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipSortByMetric":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 6fafe59c-0fec-4cd8-a8b3-c0bfaffb2135 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_4.yaml b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_4.yaml deleted file mode 100644 index 93c1bf239..000000000 --- a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_4.yaml +++ /dev/null @@ -1,86 +0,0 @@ -slice_name: Node visit ratio monitor -description: null -certified_by: null -certification_details: null -viz_type: echarts_timeseries_bar -params: - datasource: 2__table - viz_type: echarts_timeseries_bar - slice_id: 4 - granularity_sqla: start_time - time_grain_sqla: null - time_range: No filter - metrics: - - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_9yefk3wj2g_5wbp61n0pyr - sqlExpression: null - groupby: - - flow_label - - node_label - contributionMode: column - adhoc_filters: [] - order_desc: true - row_limit: 10000 - truncate_metric: true - show_empty_columns: true - comparison_type: values - annotation_layers: [] - forecastPeriods: 10 - forecastInterval: 0.8 - orientation: vertical - x_axis_title: Datetime - x_axis_title_margin: 30 - y_axis_title: Node visit ratio - y_axis_title_margin: 50 - y_axis_title_position: Left - color_scheme: supersetColors - stack: true - only_total: true - zoomable: true - show_legend: true - legendType: scroll - legendOrientation: top - x_axis_time_format: smart_date - xAxisLabelRotation: 45 - y_axis_format: SMART_NUMBER - logAxis: false - minorSplitLine: false - truncateYAxis: false - y_axis_bounds: - - null - - null - rich_tooltip: true - tooltipSortByMetric: true - tooltipTimeFormat: smart_date - extra_form_data: {} - dashboards: - - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":["flow_label","node_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["flow_label","node_label"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["flow_label","node_label"],"aggregates":{"COUNT(context_id)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(context_id)":null},"level":0,"inplace":true}},{"operation":"contribution","options":{"orientation":"column"}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":4,"granularity_sqla":"start_time","time_grain_sqla":null,"time_range":"No - filter","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_9yefk3wj2g_5wbp61n0pyr","sqlExpression":null}],"groupby":["flow_label","node_label"],"contributionMode":"column","adhoc_filters":[],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title":"Datetime","x_axis_title_margin":30,"y_axis_title":"Node - visit ratio","y_axis_title_margin":50,"y_axis_title_position":"Left","color_scheme":"supersetColors","stack":true,"only_total":true,"zoomable":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","xAxisLabelRotation":45,"y_axis_format":"SMART_NUMBER","logAxis":false,"minorSplitLine":false,"truncateYAxis":false,"y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipSortByMetric":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' -cache_timeout: null -uuid: 6fafe59c-0fec-4cd8-a8b3-c0bfaffb2135 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visits_cloud_5.yaml b/dff/config/superset_dashboard/charts/Node_visits_cloud_5.yaml deleted file mode 100644 index 334bc85c7..000000000 --- a/dff/config/superset_dashboard/charts/Node_visits_cloud_5.yaml +++ /dev/null @@ -1,48 +0,0 @@ -slice_name: Node visits [cloud] -description: null -certified_by: null -certification_details: null -viz_type: word_cloud -params: - adhoc_filters: [] - color_scheme: supersetColors - datasource: 1__table - extra_form_data: {} - granularity_sqla: start_time - metric: - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_mmbslhy6cnd_6zv1lh26whx - sqlExpression: null - rotation: flat - row_limit: 500 - series: label - size_from: 10 - size_to: 80 - time_range: No filter - viz_type: word_cloud -query_context: null -cache_timeout: null -uuid: b25b4292-ff21-4164-98ac-b1cba95e2994 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml b/dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml new file mode 100644 index 000000000..939773692 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml @@ -0,0 +1,91 @@ +slice_name: Node visits [ratio] +description: null +certified_by: null +certification_details: null +viz_type: pie +params: + datasource: 2__table + viz_type: pie + slice_id: 3 + granularity_sqla: start_time + time_range: No filter + groupby: + - flow_label + - node_label + metric: + aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_lk827d91wws_mq94n624y6 + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_cikhjlv8d6v_qtfsor113yg + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_jnqs9l8t2wl_gn1f9vyfaeh + row_limit: 100 + sort_by_metric: true + color_scheme: echarts4Colors + show_labels_threshold: 5 + show_legend: true + legendType: plain + legendOrientation: top + legendMargin: 100 + label_type: key + number_format: SMART_NUMBER + date_format: smart_date + show_labels: true + labels_outside: true + label_line: false + show_total: true + outerRadius: 70 + donut: true + innerRadius: 36 + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["flow_label","node_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null},false]],"annotation_layers":[],"row_limit":100,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"pie","slice_id":3,"granularity_sqla":"start_time","time_range":"No + filter","groupby":["flow_label","node_label"],"metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null},"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_cikhjlv8d6v_qtfsor113yg"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_jnqs9l8t2wl_gn1f9vyfaeh"}],"row_limit":100,"sort_by_metric":true,"color_scheme":"echarts4Colors","show_labels_threshold":5,"show_legend":true,"legendType":"plain","legendOrientation":"top","legendMargin":100,"label_type":"key","number_format":"SMART_NUMBER","date_format":"smart_date","show_labels":true,"labels_outside":true,"label_line":false,"show_total":true,"outerRadius":70,"donut":true,"innerRadius":36,"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: f9fb7893-3533-4519-bbc4-1f4853f380e1 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml b/dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml deleted file mode 100644 index f3d71f8e9..000000000 --- a/dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml +++ /dev/null @@ -1,65 +0,0 @@ -slice_name: Node visits [ratio] -description: null -certified_by: null -certification_details: null -viz_type: pie -params: - adhoc_filters: [] - color_scheme: supersetColors - datasource: 1__table - date_format: smart_date - donut: true - extra_form_data: {} - granularity_sqla: start_time - groupby: - - flow_label - - node_label - innerRadius: 36 - label_line: false - label_type: key - labels_outside: true - legendMargin: 100 - legendOrientation: top - legendType: plain - metric: - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_lk827d91wws_mq94n624y6 - sqlExpression: null - number_format: SMART_NUMBER - outerRadius: 70 - row_limit: 100 - show_labels: true - show_labels_threshold: 5 - show_legend: true - show_total: true - sort_by_metric: true - time_range: No filter - viz_type: pie -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":["flow_label","node_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null},false]],"annotation_layers":[],"row_limit":100,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"adhoc_filters":[],"color_scheme":"supersetColors","datasource":"2__table","date_format":"smart_date","donut":true,"extra_form_data":{},"granularity_sqla":"start_time","groupby":["flow_label","node_label"],"innerRadius":36,"label_line":false,"label_type":"key","labels_outside":true,"legendMargin":100,"legendOrientation":"top","legendType":"plain","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_lk827d91wws_mq94n624y6","sqlExpression":null},"number_format":"SMART_NUMBER","outerRadius":70,"row_limit":100,"show_labels":true,"show_labels_threshold":5,"show_legend":true,"show_total":true,"slice_id":6,"sort_by_metric":true,"time_range":"No - filter","viz_type":"pie","force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' -cache_timeout: null -uuid: f9fb7893-3533-4519-bbc4-1f4853f380e1 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml b/dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml new file mode 100644 index 000000000..f39969b18 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml @@ -0,0 +1,76 @@ +slice_name: Node visits [sunburst] +description: null +certified_by: null +certification_details: null +viz_type: sunburst +params: + datasource: 2__table + viz_type: sunburst + slice_id: 10 + granularity_sqla: start_time + time_range: No filter + groupby: + - flow_label + - node_label + metric: + aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_7mo9cnw40ph_rzxhx01jm0c + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_k9appc49vwn_3maud61tywi + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_6s6c2atm24m_3fhzyn98hbs + row_limit: 10000 + color_scheme: echarts4Colors + linear_color_scheme: superset_seq_1 + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''')"},"applied_time_extras":{},"columns":["flow_label","node_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_7mo9cnw40ph_rzxhx01jm0c","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"sunburst","slice_id":10,"granularity_sqla":"start_time","time_range":"No + filter","groupby":["flow_label","node_label"],"metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_7mo9cnw40ph_rzxhx01jm0c","sqlExpression":null},"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_k9appc49vwn_3maud61tywi"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_6s6c2atm24m_3fhzyn98hbs"}],"row_limit":10000,"color_scheme":"echarts4Colors","linear_color_scheme":"superset_seq_1","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: e955f48c-824c-423c-a11c-5b5dca162927 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Node_visits_sunburst_7.yaml b/dff/config/superset_dashboard/charts/Node_visits_sunburst_7.yaml deleted file mode 100644 index b3293a635..000000000 --- a/dff/config/superset_dashboard/charts/Node_visits_sunburst_7.yaml +++ /dev/null @@ -1,69 +0,0 @@ -slice_name: Node visits [sunburst] -description: null -certified_by: null -certification_details: null -viz_type: sunburst -params: - adhoc_filters: - - clause: WHERE - comparator: null - expressionType: SIMPLE - filterOptionName: filter_82x0yx6fkpv_6h8a2190nmh - isExtra: false - isNew: false - operator: IS NOT NULL - operatorId: IS_NOT_NULL - sqlExpression: null - subject: flow_label - - clause: WHERE - comparator: null - expressionType: SIMPLE - filterOptionName: filter_653tn7jqmox_x65gwtz29gc - isExtra: false - isNew: false - operator: IS NOT NULL - operatorId: IS_NOT_NULL - sqlExpression: null - subject: node_label - color_scheme: supersetColors - datasource: 3__table - extra_form_data: {} - granularity_sqla: start_time - groupby: - - flow_label - - node_label - linear_color_scheme: superset_seq_1 - metric: - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_7mo9cnw40ph_rzxhx01jm0c - sqlExpression: null - row_limit: 10000 - slice_id: 8 - time_range: No filter - viz_type: sunburst -query_context: null -cache_timeout: null -uuid: e955f48c-824c-423c-a11c-5b5dca162927 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml b/dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml new file mode 100644 index 000000000..cc13f303d --- /dev/null +++ b/dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml @@ -0,0 +1,92 @@ +slice_name: Rating slot [line chart] +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_line +params: + datasource: 2__table + viz_type: echarts_timeseries_line + slice_id: 17 + granularity_sqla: start_time + time_grain_sqla: PT1M + time_range: No filter + metrics: + - aggregate: null + column: null + datasourceWarning: false + expressionType: SQL + hasCustomLabel: false + label: AVG(CAST(JSON_VALUE(data, '$.rating') AS... + optionName: metric_00oy6lz4f1x8m_ogwvyq0hxx + sqlExpression: AVG(CAST(JSON_VALUE(data, '$.rating') AS Int16)) + groupby: [] + adhoc_filters: + - clause: WHERE + comparator: get_slots + datasourceWarning: false + expressionType: SIMPLE + filterOptionName: filter_7obcf0exa9_1e58m260tq5 + isExtra: false + isNew: false + operator: == + operatorId: EQUALS + sqlExpression: null + subject: data_key + - clause: WHERE + comparator: null + datasourceWarning: false + expressionType: SQL + filterOptionName: filter_0sg816yobyac_obqceo13prc + isExtra: false + isNew: false + operator: null + sqlExpression: JSON_VALUE(data, '$.rating') <> '' + subject: null + order_desc: true + row_limit: 10000 + truncate_metric: true + show_empty_columns: true + comparison_type: values + annotation_layers: [] + forecastPeriods: 10 + forecastInterval: 0.8 + x_axis_title: Time axis + x_axis_title_margin: 30 + y_axis_title: Average rating + y_axis_title_margin: 30 + y_axis_title_position: Left + color_scheme: echarts4Colors + seriesType: line + only_total: true + opacity: 0.2 + markerSize: 6 + show_legend: true + legendType: scroll + legendOrientation: top + x_axis_time_format: smart_date + rich_tooltip: true + tooltipTimeFormat: smart_date + y_axis_format: SMART_NUMBER + y_axis_bounds: + - null + - null + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(JSON_VALUE(data, + ''$.rating'') <> '''')"},"applied_time_extras":{},"columns":[],"metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS Int16))"}],"orderby":[[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS Int16))"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":[],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":[],"aggregates":{"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS...":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_line","slice_id":17,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No + filter","metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, + ''$.rating'') AS Int16))"}],"groupby":[],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_7obcf0exa9_1e58m260tq5","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_0sg816yobyac_obqceo13prc","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, + ''$.rating'') <> ''''","subject":null}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title":"Time + axis","x_axis_title_margin":30,"y_axis_title":"Average rating","y_axis_title_margin":30,"y_axis_title_position":"Left","color_scheme":"echarts4Colors","seriesType":"line","only_total":true,"opacity":0.2,"markerSize":6,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 128e1da2-1efd-433d-9b93-a07de175e2bc +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Service_load_max_dialogue_length_8.yaml b/dff/config/superset_dashboard/charts/Service_load_max_dialogue_length_8.yaml deleted file mode 100644 index 1e087769a..000000000 --- a/dff/config/superset_dashboard/charts/Service_load_max_dialogue_length_8.yaml +++ /dev/null @@ -1,83 +0,0 @@ -slice_name: Service load [max dialogue length] -description: null -certified_by: null -certification_details: null -viz_type: echarts_timeseries_step -params: - datasource: 2__table - viz_type: echarts_timeseries_step - slice_id: 8 - granularity_sqla: start_time - time_grain_sqla: null - time_range: No filter - metrics: - - aggregate: null - column: null - datasourceWarning: false - expressionType: SQL - hasCustomLabel: false - label: AVG(CAST(request_id AS Int16)) - optionName: metric_8h0zfurdcy_tzo5q0tuczi - sqlExpression: AVG(CAST(request_id AS Int16)) - - aggregate: null - column: null - datasourceWarning: false - expressionType: SQL - hasCustomLabel: false - label: MAX(CAST(request_id AS Int16)) - optionName: metric_wz5zx1kqqc_u42eslame2 - sqlExpression: MAX(CAST(request_id AS Int16)) - groupby: [] - adhoc_filters: [] - order_desc: true - row_limit: 10000 - truncate_metric: true - show_empty_columns: true - comparison_type: values - annotation_layers: [] - forecastPeriods: 10 - forecastInterval: 0.8 - x_axis_title_margin: 15 - y_axis_title: AVG/MAX dialogue length - y_axis_title_margin: 50 - y_axis_title_position: Left - color_scheme: supersetColors - seriesType: start - only_total: true - opacity: 0.2 - markerSize: 6 - zoomable: true - show_legend: true - legendType: scroll - legendOrientation: top - x_axis_time_format: smart_date - rich_tooltip: true - tooltipSortByMetric: false - tooltipTimeFormat: smart_date - y_axis_format: SMART_NUMBER - logAxis: false - y_axis_bounds: - - null - - null - extra_form_data: {} - dashboards: - - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":[],"metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(request_id - AS Int16))","optionName":"metric_8h0zfurdcy_tzo5q0tuczi","sqlExpression":"AVG(CAST(request_id - AS Int16))"},{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"MAX(CAST(request_id - AS Int16))","optionName":"metric_wz5zx1kqqc_u42eslame2","sqlExpression":"MAX(CAST(request_id - AS Int16))"}],"orderby":[[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(request_id - AS Int16))","optionName":"metric_8h0zfurdcy_tzo5q0tuczi","sqlExpression":"AVG(CAST(request_id - AS Int16))"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":[],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":[],"aggregates":{"AVG(CAST(request_id - AS Int16))":{"operator":"mean"},"MAX(CAST(request_id AS Int16))":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_step","slice_id":8,"granularity_sqla":"start_time","time_grain_sqla":null,"time_range":"No - filter","metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(request_id - AS Int16))","optionName":"metric_8h0zfurdcy_tzo5q0tuczi","sqlExpression":"AVG(CAST(request_id - AS Int16))"},{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"MAX(CAST(request_id - AS Int16))","optionName":"metric_wz5zx1kqqc_u42eslame2","sqlExpression":"MAX(CAST(request_id - AS Int16))"}],"groupby":[],"adhoc_filters":[],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title_margin":15,"y_axis_title":"AVG/MAX - dialogue length","y_axis_title_margin":50,"y_axis_title_position":"Left","color_scheme":"supersetColors","seriesType":"start","only_total":true,"opacity":0.2,"markerSize":6,"zoomable":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"tooltipSortByMetric":false,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","logAxis":false,"y_axis_bounds":[null,null],"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' -cache_timeout: null -uuid: 276c3aa7-89bc-49ff-91b6-6232ae35c854 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Service_load_users_9.yaml b/dff/config/superset_dashboard/charts/Service_load_users_4.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Service_load_users_9.yaml rename to dff/config/superset_dashboard/charts/Service_load_users_4.yaml diff --git a/dff/config/superset_dashboard/charts/Table_10.yaml b/dff/config/superset_dashboard/charts/Table_10.yaml deleted file mode 100644 index b3f9f636c..000000000 --- a/dff/config/superset_dashboard/charts/Table_10.yaml +++ /dev/null @@ -1,34 +0,0 @@ -slice_name: Table -description: null -certified_by: null -certification_details: null -viz_type: table -params: - adhoc_filters: [] - all_columns: [] - color_pn: true - datasource: 3__table - extra_form_data: {} - granularity_sqla: start_time - groupby: - - context_id - - start_time - - data_key - - data - order_by_cols: [] - order_desc: false - percent_metrics: [] - query_mode: aggregate - row_limit: 10000 - server_page_length: 10 - show_cell_bars: true - slice_id: 14 - table_timestamp_format: smart_date - time_grain_sqla: null - time_range: No filter - viz_type: table -query_context: null -cache_timeout: null -uuid: 38d353dc-c0ef-41a0-97c7-3dcbebab9e02 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Table_14.yaml b/dff/config/superset_dashboard/charts/Table_14.yaml new file mode 100644 index 000000000..00c9ced03 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Table_14.yaml @@ -0,0 +1,36 @@ +slice_name: Table +description: null +certified_by: null +certification_details: null +viz_type: table +params: + adhoc_filters: [] + all_columns: [] + color_pn: true + datasource: 3__table + extra_form_data: {} + granularity_sqla: start_time + groupby: + - context_id + - start_time + - data_key + - data + order_by_cols: [] + order_desc: false + percent_metrics: [] + query_mode: aggregate + row_limit: 10000 + server_page_length: 10 + show_cell_bars: true + slice_id: 14 + table_timestamp_format: smart_date + time_grain_sqla: null + time_range: No filter + viz_type: table +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":["context_id","start_time","data_key","data"],"metrics":[],"orderby":[],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":false,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"adhoc_filters":[],"all_columns":[],"color_pn":true,"datasource":"2__table","extra_form_data":{},"granularity_sqla":"start_time","groupby":["context_id","start_time","data_key","data"],"order_by_cols":[],"order_desc":false,"percent_metrics":[],"query_mode":"aggregate","row_limit":10000,"server_page_length":10,"show_cell_bars":true,"slice_id":14,"table_timestamp_format":"smart_date","time_grain_sqla":null,"time_range":"No + filter","viz_type":"table","force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 38d353dc-c0ef-41a0-97c7-3dcbebab9e02 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Terminal_labels_11.yaml b/dff/config/superset_dashboard/charts/Terminal_labels_7.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Terminal_labels_11.yaml rename to dff/config/superset_dashboard/charts/Terminal_labels_7.yaml diff --git a/dff/config/superset_dashboard/charts/Transition_counts_1.yaml b/dff/config/superset_dashboard/charts/Transition_counts_1.yaml new file mode 100644 index 000000000..56c6099f9 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Transition_counts_1.yaml @@ -0,0 +1,101 @@ +slice_name: Transition counts +description: null +certified_by: null +certification_details: null +viz_type: dist_bar +params: + datasource: 2__table + viz_type: dist_bar + slice_id: 1 + granularity_sqla: start_time + time_range: No filter + metrics: + - aggregate: COUNT_DISTINCT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT_DISTINCT(context_id) + optionName: metric_tc3lb0a1pff_dyroibp08h7 + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_f7v0qac48fr_l37sg1wvtm + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_e9h83eu2wg_ata0o82djjn + - expressionType: SQL + sqlExpression: prev_label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_t2quebiqkp_x1qhr9mtq7f + groupby: + - prev_label + - label + columns: + - flow_label + row_limit: 10000 + order_desc: true + color_scheme: echarts4Colors + show_legend: true + rich_tooltip: true + bar_stacked: true + y_axis_format: SMART_NUMBER + y_axis_label: Counts + y_axis_showminmax: false + y_axis_bounds: + - null + - null + x_axis_label: Transitions + bottom_margin: auto + x_ticks_layout: auto + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''') AND (prev_label <> '''')"},"applied_time_extras":{},"columns":["prev_label","label","flow_label"],"metrics":[{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_tc3lb0a1pff_dyroibp08h7","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":1,"granularity_sqla":"start_time","time_range":"No + filter","metrics":[{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_tc3lb0a1pff_dyroibp08h7","sqlExpression":null}],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_f7v0qac48fr_l37sg1wvtm"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_e9h83eu2wg_ata0o82djjn"},{"expressionType":"SQL","sqlExpression":"prev_label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_t2quebiqkp_x1qhr9mtq7f"}],"groupby":["prev_label","label"],"columns":["flow_label"],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"y_axis_format":"SMART_NUMBER","y_axis_label":"Counts","y_axis_showminmax":false,"y_axis_bounds":[null,null],"x_axis_label":"Transitions","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 9fcc7cc1-9257-4c0d-b377-b3a60a8bf3df +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Transition_counts_12.yaml b/dff/config/superset_dashboard/charts/Transition_counts_12.yaml deleted file mode 100644 index f44c72191..000000000 --- a/dff/config/superset_dashboard/charts/Transition_counts_12.yaml +++ /dev/null @@ -1,63 +0,0 @@ -slice_name: Transition counts -description: null -certified_by: null -certification_details: null -viz_type: dist_bar -params: - adhoc_filters: [] - bar_stacked: true - bottom_margin: auto - color_scheme: supersetColors - columns: - - flow_label - datasource: 1__table - extra_form_data: {} - granularity_sqla: start_time - groupby: - - prev_label - - label - metrics: - - aggregate: COUNT_DISTINCT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT_DISTINCT(context_id) - optionName: metric_tc3lb0a1pff_dyroibp08h7 - sqlExpression: null - order_desc: true - rich_tooltip: true - row_limit: 10000 - show_legend: true - slice_id: 6 - time_range: No filter - viz_type: dist_bar - x_axis_label: Transitions - x_ticks_layout: auto - y_axis_bounds: - - null - - null - y_axis_format: SMART_NUMBER - y_axis_label: Counts - y_axis_showminmax: false -query_context: null -cache_timeout: null -uuid: 9fcc7cc1-9257-4c0d-b377-b3a60a8bf3df -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Transition_layout_13.yaml b/dff/config/superset_dashboard/charts/Transition_layout_13.yaml deleted file mode 100644 index 5999b30ed..000000000 --- a/dff/config/superset_dashboard/charts/Transition_layout_13.yaml +++ /dev/null @@ -1,62 +0,0 @@ -slice_name: Transition layout -description: null -certified_by: null -certification_details: null -viz_type: graph_chart -params: - adhoc_filters: [] - baseEdgeWidth: 3 - baseNodeSize: 20 - color_scheme: supersetColors - datasource: 1__table - draggable: false - edgeLength: 400 - edgeSymbol: none,arrow - extra_form_data: {} - friction: 0.2 - granularity_sqla: start_time - gravity: 0.3 - layout: force - legendOrientation: top - legendType: scroll - metric: - aggregate: COUNT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT(context_id) - optionName: metric_qxsyaujh63_4b75kyx6b5g - sqlExpression: null - repulsion: 1000 - roam: scale - row_limit: 10000 - selectedMode: single - show_legend: true - source: prev_label - source_category: flow_label - target: label - target_category: flow_label - time_range: No filter - viz_type: graph_chart -query_context: null -cache_timeout: null -uuid: 801e8c66-f693-46e3-a9a5-7b2b0b08a4a7 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Transition_layout_8.yaml b/dff/config/superset_dashboard/charts/Transition_layout_8.yaml new file mode 100644 index 000000000..fd22359b5 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Transition_layout_8.yaml @@ -0,0 +1,101 @@ +slice_name: Transition layout +description: null +certified_by: null +certification_details: null +viz_type: graph_chart +params: + datasource: 2__table + viz_type: graph_chart + slice_id: 8 + granularity_sqla: start_time + time_range: No filter + source: prev_label + target: label + metric: + aggregate: COUNT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT(context_id) + optionName: metric_qxsyaujh63_4b75kyx6b5g + sqlExpression: null + source_category: flow_label + target_category: flow_label + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_avle3r80zu4_c4684cbrjfg + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_0jip6y1w3awu_eysm19dnp2 + - expressionType: SQL + sqlExpression: prev_label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_29oq8kbalhr_6wudwxysro + row_limit: 10000 + color_scheme: echarts4Colors + show_legend: true + legendType: scroll + legendOrientation: top + layout: force + edgeSymbol: none,arrow + draggable: false + roam: scale + selectedMode: single + baseNodeSize: 20 + baseEdgeWidth: 3 + edgeLength: 400 + gravity: 0.3 + repulsion: 1000 + friction: 0.2 + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''') AND (prev_label <> '''')"},"applied_time_extras":{},"columns":["prev_label","label","flow_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_qxsyaujh63_4b75kyx6b5g","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"graph_chart","slice_id":8,"granularity_sqla":"start_time","time_range":"No + filter","source":"prev_label","target":"label","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_qxsyaujh63_4b75kyx6b5g","sqlExpression":null},"source_category":"flow_label","target_category":"flow_label","adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_avle3r80zu4_c4684cbrjfg"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_0jip6y1w3awu_eysm19dnp2"},{"expressionType":"SQL","sqlExpression":"prev_label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_29oq8kbalhr_6wudwxysro"}],"row_limit":10000,"color_scheme":"echarts4Colors","show_legend":true,"legendType":"scroll","legendOrientation":"top","layout":"force","edgeSymbol":"none,arrow","draggable":false,"roam":"scale","selectedMode":"single","baseNodeSize":20,"baseEdgeWidth":3,"edgeLength":400,"gravity":0.3,"repulsion":1000,"friction":0.2,"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 801e8c66-f693-46e3-a9a5-7b2b0b08a4a7 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml b/dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml new file mode 100644 index 000000000..5083aa859 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml @@ -0,0 +1,86 @@ +slice_name: Transition ratio [chord] +description: null +certified_by: null +certification_details: null +viz_type: chord +params: + datasource: 2__table + viz_type: chord + slice_id: 12 + granularity_sqla: start_time + time_range: No filter + groupby: label + columns: prev_label + metric: + aggregate: COUNT_DISTINCT + column: + advanced_data_type: null + certification_details: null + certified_by: null + column_name: context_id + description: null + expression: null + filterable: true + groupby: true + id: 1 + is_certified: false + is_dttm: false + python_date_format: null + type: STRING + type_generic: 1 + verbose_name: null + warning_markdown: null + expressionType: SIMPLE + hasCustomLabel: false + isNew: false + label: COUNT_DISTINCT(context_id) + optionName: metric_97lz5hqft8j_aqofzpt1ma5 + sqlExpression: null + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_current_label + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_ug6txpdjuzj_znl0zrda72n + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_a4j5xkh81f5_k2i0586j12h + - expressionType: SQL + sqlExpression: prev_label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_p4zwr1yr4v9_avka1ppurai + row_limit: 10000 + y_axis_format: ~g + color_scheme: echarts4Colors + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label + <> '''') AND (prev_label <> '''')"},"applied_time_extras":{},"columns":["label","prev_label"],"metrics":[{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_97lz5hqft8j_aqofzpt1ma5","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"chord","slice_id":12,"granularity_sqla":"start_time","time_range":"No + filter","groupby":"label","columns":"prev_label","metric":{"aggregate":"COUNT_DISTINCT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT_DISTINCT(context_id)","optionName":"metric_97lz5hqft8j_aqofzpt1ma5","sqlExpression":null},"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_ug6txpdjuzj_znl0zrda72n"},{"expressionType":"SQL","sqlExpression":"label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_a4j5xkh81f5_k2i0586j12h"},{"expressionType":"SQL","sqlExpression":"prev_label + <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_p4zwr1yr4v9_avka1ppurai"}],"row_limit":10000,"y_axis_format":"~g","color_scheme":"echarts4Colors","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 388d2359-8d13-4795-8dc9-1cb5dfa92ee1 +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Transition_ratio_chord_14.yaml b/dff/config/superset_dashboard/charts/Transition_ratio_chord_14.yaml deleted file mode 100644 index e9d1f8723..000000000 --- a/dff/config/superset_dashboard/charts/Transition_ratio_chord_14.yaml +++ /dev/null @@ -1,48 +0,0 @@ -slice_name: Transition ratio [chord] -description: null -certified_by: null -certification_details: null -viz_type: chord -params: - adhoc_filters: [] - color_scheme: bnbColors - columns: prev_label - datasource: 1__table - extra_form_data: {} - granularity_sqla: start_time - groupby: label - metric: - aggregate: COUNT_DISTINCT - column: - advanced_data_type: null - certification_details: null - certified_by: null - column_name: context_id - description: null - expression: null - filterable: true - groupby: true - id: 1 - is_certified: false - is_dttm: false - python_date_format: null - type: STRING - type_generic: 1 - verbose_name: null - warning_markdown: null - expressionType: SIMPLE - hasCustomLabel: false - isNew: false - label: COUNT_DISTINCT(context_id) - optionName: metric_97lz5hqft8j_aqofzpt1ma5 - sqlExpression: null - row_limit: 10000 - slice_id: 13 - time_range: No filter - viz_type: chord - y_axis_format: ~g -query_context: null -cache_timeout: null -uuid: 388d2359-8d13-4795-8dc9-1cb5dfa92ee1 -version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/dashboards/DFF_Stats_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_Stats_1.yaml deleted file mode 100644 index 0523b8ae1..000000000 --- a/dff/config/superset_dashboard/dashboards/DFF_Stats_1.yaml +++ /dev/null @@ -1,555 +0,0 @@ -dashboard_title: DFF Stats -description: null -css: '' -slug: dff-stats -uuid: 68bce374-99bc-4890-b8c2-cb172409b894 -position: - CHART-Af3zvLsiKV: - children: [] - id: CHART-Af3zvLsiKV - meta: - chartId: 4 - height: 66 - sliceName: Node visit ratio monitor - uuid: 6fafe59c-0fec-4cd8-a8b3-c0bfaffb2135 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - - ROW-7g6_n72hZ - type: CHART - CHART-CuCYDOlGEu: - children: [] - id: CHART-CuCYDOlGEu - meta: - chartId: 10 - height: 50 - sliceName: Table - sliceNameOverride: Stats table - uuid: 38d353dc-c0ef-41a0-97c7-3dcbebab9e02 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-JCU6rANFP - - ROW-EaYAQjv4W - type: CHART - CHART-DxY0c3RnIv: - children: [] - id: CHART-DxY0c3RnIv - meta: - chartId: 3 - height: 61 - sliceName: Node counts - uuid: 0c47c7b5-f500-46cb-97e3-9ebb637f0c8a - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-VUknWnOAy - - ROW-PvToekFjO - type: CHART - CHART-explore-10-1: - children: [] - id: CHART-explore-10-1 - meta: - chartId: 13 - height: 73 - sliceName: Transition layout - sliceNameOverride: Dialogue layout - uuid: 801e8c66-f693-46e3-a9a5-7b2b0b08a4a7 - width: 6 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-JCU6rANFP - - ROW-Ccs1FbcI- - type: CHART - CHART-explore-11-1: - children: [] - id: CHART-explore-11-1 - meta: - chartId: 5 - height: 56 - sliceName: Node visits [cloud] - uuid: b25b4292-ff21-4164-98ac-b1cba95e2994 - width: 8 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - - ROW-rR4J0eAhh - type: CHART - CHART-explore-13-1: - children: [] - id: CHART-explore-13-1 - meta: - chartId: 14 - height: 74 - sliceName: Transition ratio [chord] - uuid: 388d2359-8d13-4795-8dc9-1cb5dfa92ee1 - width: 6 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-JCU6rANFP - - ROW-Ccs1FbcI- - type: CHART - CHART-explore-14-1: - children: [] - id: CHART-explore-14-1 - meta: - chartId: 7 - height: 105 - sliceName: Node visits [sunburst] - uuid: e955f48c-824c-423c-a11c-5b5dca162927 - width: 6 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - - ROW-ZcN9G9RL5 - type: CHART - CHART-explore-20-1: - children: [] - id: CHART-explore-20-1 - meta: - chartId: 2 - height: 50 - sliceName: Node Visits - uuid: 44f4ab9d-5072-4926-a6ed-8615fb81b3d0 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - - ROW-ksepbeQu6 - type: CHART - CHART-explore-21-1: - children: [] - id: CHART-explore-21-1 - meta: - chartId: 1 - height: 60 - sliceName: Flow visit ratio monitor - uuid: ba02528b-184b-4304-b027-f2b7d9011ab0 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - - ROW-ZTVWOu2o0 - type: CHART - CHART-explore-22-1: - children: [] - id: CHART-explore-22-1 - meta: - chartId: 11 - height: 61 - sliceName: Terminal labels - sliceNameOverride: Terminal labels monitor - uuid: cf066e41-a9e8-4f54-a875-ebf4da350b59 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - - ROW-LhKWfqM7V - type: CHART - CHART-explore-9-1: - children: [] - id: CHART-explore-9-1 - meta: - chartId: 6 - height: 105 - sliceName: Node visits [ratio] - uuid: f9fb7893-3533-4519-bbc4-1f4853f380e1 - width: 6 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - - ROW-ZcN9G9RL5 - type: CHART - CHART-mYC2udeF3a: - children: [] - id: CHART-mYC2udeF3a - meta: - chartId: 9 - height: 50 - sliceName: Service load [users] - uuid: b5d43314-514c-464e-9fcc-f897e3ae0963 - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - - ROW-Ae7v1prsp2 - type: CHART - CHART-wci7CHiza6: - children: [] - id: CHART-wci7CHiza6 - meta: - chartId: 12 - height: 66 - sliceName: Transition counts - uuid: 9fcc7cc1-9257-4c0d-b377-b3a60a8bf3df - width: 12 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-VUknWnOAy - - ROW-TRNUnY9X_Y - type: CHART - COLUMN-JRaDi96UVP: - children: [] - id: COLUMN-JRaDi96UVP - meta: - background: BACKGROUND_TRANSPARENT - width: 2 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - - ROW-rR4J0eAhh - type: COLUMN - COLUMN-WysgPuf0P1: - children: [] - id: COLUMN-WysgPuf0P1 - meta: - background: BACKGROUND_TRANSPARENT - width: 2 - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - - ROW-rR4J0eAhh - type: COLUMN - DASHBOARD_VERSION_KEY: v2 - GRID_ID: - children: - - HEADER-nYVwogYInk - - TABS-Xoi5oUBxZI - id: GRID_ID - parents: - - ROOT_ID - type: GRID - HEADER-nYVwogYInk: - children: [] - id: HEADER-nYVwogYInk - meta: - background: BACKGROUND_TRANSPARENT - headerSize: LARGE_HEADER - text: DFF Stats - parents: - - ROOT_ID - - GRID_ID - type: HEADER - HEADER_ID: - id: HEADER_ID - meta: - text: DFF Stats - type: HEADER - ROOT_ID: - children: - - GRID_ID - id: ROOT_ID - type: ROOT - ROW-7g6_n72hZ: - children: - - CHART-Af3zvLsiKV - id: ROW-7g6_n72hZ - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - type: ROW - ROW-Ae7v1prsp2: - children: - - CHART-mYC2udeF3a - id: ROW-Ae7v1prsp2 - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - type: ROW - ROW-Ccs1FbcI-: - children: - - CHART-explore-10-1 - - CHART-explore-13-1 - id: ROW-Ccs1FbcI- - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-JCU6rANFP - type: ROW - ROW-EaYAQjv4W: - children: - - CHART-CuCYDOlGEu - id: ROW-EaYAQjv4W - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-JCU6rANFP - type: ROW - ROW-LhKWfqM7V: - children: - - CHART-explore-22-1 - id: ROW-LhKWfqM7V - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - type: ROW - ROW-PvToekFjO: - children: - - CHART-DxY0c3RnIv - id: ROW-PvToekFjO - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-VUknWnOAy - type: ROW - ROW-TRNUnY9X_Y: - children: - - CHART-wci7CHiza6 - id: ROW-TRNUnY9X_Y - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-VUknWnOAy - type: ROW - ROW-ZTVWOu2o0: - children: - - CHART-explore-21-1 - id: ROW-ZTVWOu2o0 - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - type: ROW - ROW-ZcN9G9RL5: - children: - - CHART-explore-9-1 - - CHART-explore-14-1 - id: ROW-ZcN9G9RL5 - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - type: ROW - ROW-hfJk2ddHi: - children: - - CHART-explore-20-1 - id: ROW-hfJk2ddHi - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-VUknWnOAy - type: ROW - ROW-ksepbeQu6: - children: - - CHART-explore-20-1 - id: ROW-ksepbeQu6 - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-6zE8noCIsx - type: ROW - ROW-rR4J0eAhh: - children: - - COLUMN-JRaDi96UVP - - CHART-explore-11-1 - - COLUMN-WysgPuf0P1 - id: ROW-rR4J0eAhh - meta: - background: BACKGROUND_TRANSPARENT - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - - TAB-Gw0Ffh1lG - type: ROW - TAB-6zE8noCIsx: - children: - - ROW-Ae7v1prsp2 - - ROW-ksepbeQu6 - - ROW-ZTVWOu2o0 - - ROW-7g6_n72hZ - - ROW-LhKWfqM7V - id: TAB-6zE8noCIsx - meta: - defaultText: Tab title - placeholder: Tab title - text: Service stats - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - type: TAB - TAB-Gw0Ffh1lG: - children: - - ROW-ZcN9G9RL5 - - ROW-rR4J0eAhh - id: TAB-Gw0Ffh1lG - meta: - defaultText: Tab title - placeholder: Tab title - text: General stats - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - type: TAB - TAB-JCU6rANFP: - children: - - ROW-EaYAQjv4W - - ROW-Ccs1FbcI- - id: TAB-JCU6rANFP - meta: - defaultText: Tab title - placeholder: Tab title - text: Overview - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - type: TAB - TAB-VUknWnOAy: - children: - - ROW-PvToekFjO - - ROW-hfJk2ddHi - - ROW-TRNUnY9X_Y - id: TAB-VUknWnOAy - meta: - defaultText: Tab title - placeholder: Tab title - text: Additional stats - parents: - - ROOT_ID - - GRID_ID - - TABS-Xoi5oUBxZI - type: TAB - TABS-Xoi5oUBxZI: - children: - - TAB-JCU6rANFP - - TAB-Gw0Ffh1lG - - TAB-VUknWnOAy - - TAB-6zE8noCIsx - id: TABS-Xoi5oUBxZI - meta: {} - parents: - - ROOT_ID - - GRID_ID - type: TABS -metadata: - color_scheme: echarts4Colors - label_colors: {} - shared_label_colors: - 'greeting_flow: node1': '#c23531' - 'greeting_flow: node2': '#2f4554' - 'greeting_flow: node3': '#61a0a8' - 'greeting_flow: node4': '#d48265' - greeting_flow, node1: '#c23531' - greeting_flow, node2: '#2f4554' - greeting_flow, node3: '#61a0a8' - greeting_flow, node4: '#d48265' - greeting_flow: '#c23531' - AVG(CAST(request_id AS Int16)): '#c23531' - MAX(CAST(request_id AS Int16)): '#2f4554' - root: '#c23531' - node2: '#61a0a8' - node4: '#d48265' - node3: '#91c7ae' - node1: '#749f83' - ? '' - : '#c23531' - timed_refresh_immune_slices: [] - expanded_slices: {} - refresh_frequency: 1800 - show_native_filters: true - default_filters: '{}' - chart_configuration: {} - color_scheme_domain: - - '#c23531' - - '#2f4554' - - '#61a0a8' - - '#d48265' - - '#91c7ae' - - '#749f83' - - '#ca8622' - - '#bda29a' - - '#6e7074' - - '#546570' - - '#c4ccd3' - cross_filters_enabled: false - native_filter_configuration: - - id: NATIVE_FILTER-5vyW3SgU5 - controlValues: - enableEmptyFilter: false - name: Time grain - filterType: filter_timegrain - targets: - - datasetUuid: fda98ab8-f550-45f1-9ded-0113f3e67260 - defaultDataMask: - extraFormData: {} - filterState: {} - ownState: {} - cascadeParentIds: [] - scope: - rootPath: - - TAB-6zE8noCIsx - excluded: - - 7 - type: NATIVE_FILTER - description: '' -version: 1.0.0 diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml new file mode 100644 index 000000000..895715768 --- /dev/null +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -0,0 +1,1211 @@ +dashboard_title: DFF statistics dashboard +description: null +css: '' +slug: dff-stats +uuid: 68bce374-99bc-4890-b8c2-cb172409b894 +position: + CHART-Af3zvLsiKV: + children: [] + id: CHART-Af3zvLsiKV + meta: + chartId: 2 + height: 66 + sliceName: Node visit ratio monitor + uuid: 6fafe59c-0fec-4cd8-a8b3-c0bfaffb2135 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-7g6_n72hZ + type: CHART + CHART-CuCYDOlGEu: + children: [] + id: CHART-CuCYDOlGEu + meta: + chartId: 14 + height: 42 + sliceName: Table + sliceNameOverride: Raw data + uuid: 38d353dc-c0ef-41a0-97c7-3dcbebab9e02 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + - ROW-EaYAQjv4W + type: CHART + CHART-DxY0c3RnIv: + children: [] + id: CHART-DxY0c3RnIv + meta: + chartId: 9 + height: 61 + sliceName: Node counts + sliceNameOverride: General node visit distribution + uuid: 0c47c7b5-f500-46cb-97e3-9ebb637f0c8a + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-WirNNBBom + type: CHART + CHART-cxqeW2rGoV: + children: [] + id: CHART-cxqeW2rGoV + meta: + chartId: 6 + height: 50 + sliceName: Node Visits + sliceNameOverride: Node per dialog turn distribution + uuid: 44f4ab9d-5072-4926-a6ed-8615fb81b3d0 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-hNOZdWZpw + type: CHART + CHART-explore-10-1: + children: [] + id: CHART-explore-10-1 + meta: + chartId: 8 + height: 73 + sliceName: Transition layout + sliceNameOverride: Weighted transition graph + uuid: 801e8c66-f693-46e3-a9a5-7b2b0b08a4a7 + width: 6 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + - ROW-Ccs1FbcI- + type: CHART + CHART-explore-13-1: + children: [] + id: CHART-explore-13-1 + meta: + chartId: 12 + height: 74 + sliceName: Transition ratio [chord] + sliceNameOverride: Weighted transition graph [chord plot] + uuid: 388d2359-8d13-4795-8dc9-1cb5dfa92ee1 + width: 6 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + - ROW-Ccs1FbcI- + type: CHART + CHART-explore-14-1: + children: [] + id: CHART-explore-14-1 + meta: + chartId: 10 + height: 105 + sliceName: Node visits [sunburst] + sliceNameOverride: Node visit distribution [sunburst] + uuid: e955f48c-824c-423c-a11c-5b5dca162927 + width: 6 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-uSb7snkjI + type: CHART + CHART-explore-15-1: + children: [] + id: CHART-explore-15-1 + meta: + chartId: 15 + height: 50 + sliceName: Current topic [time series bar chart] + sliceNameOverride: Current topic slot [time series bar chart] + uuid: f8215b4d-cdaf-489a-90b2-040da840ab35 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-s_aeCbvt3 + type: CHART + CHART-explore-16-1: + children: [] + id: CHART-explore-16-1 + meta: + chartId: 16 + height: 50 + sliceName: Current topic slot [bar chart] + uuid: a70c05d0-770b-4068-a55d-934283f5b1bb + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-IsV-8cS3Z + type: CHART + CHART-explore-17-1: + children: [] + id: CHART-explore-17-1 + meta: + chartId: 17 + height: 50 + sliceName: Rating slot [line chart] + uuid: 128e1da2-1efd-433d-9b93-a07de175e2bc + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-TZwRV0tZy + type: CHART + CHART-explore-21-1: + children: [] + id: CHART-explore-21-1 + meta: + chartId: 13 + height: 60 + sliceName: Flow visit ratio monitor + uuid: ba02528b-184b-4304-b027-f2b7d9011ab0 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-ZTVWOu2o0 + type: CHART + CHART-explore-22-1: + children: [] + id: CHART-explore-22-1 + meta: + chartId: 7 + height: 61 + sliceName: Terminal labels + sliceNameOverride: Terminal labels monitor + uuid: cf066e41-a9e8-4f54-a875-ebf4da350b59 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-LhKWfqM7V + type: CHART + CHART-explore-9-1: + children: [] + id: CHART-explore-9-1 + meta: + chartId: 3 + height: 105 + sliceName: Node visits [ratio] + sliceNameOverride: Node visit distribution [ratio] + uuid: f9fb7893-3533-4519-bbc4-1f4853f380e1 + width: 6 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-uSb7snkjI + type: CHART + CHART-mYC2udeF3a: + children: [] + id: CHART-mYC2udeF3a + meta: + chartId: 4 + height: 50 + sliceName: Service load [users] + uuid: b5d43314-514c-464e-9fcc-f897e3ae0963 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-Ae7v1prsp2 + type: CHART + CHART-wci7CHiza6: + children: [] + id: CHART-wci7CHiza6 + meta: + chartId: 1 + height: 66 + sliceName: Transition counts + sliceNameOverride: General transitions distribution + uuid: 9fcc7cc1-9257-4c0d-b377-b3a60a8bf3df + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-UiCWq3ix1 + type: CHART + DASHBOARD_VERSION_KEY: v2 + GRID_ID: + children: + - TABS-Xoi5oUBxZI + id: GRID_ID + parents: + - ROOT_ID + type: GRID + HEADER_ID: + id: HEADER_ID + meta: + text: DFF statistics dashboard + type: HEADER + MARKDOWN-8Q9BhcEwva: + children: [] + id: MARKDOWN-8Q9BhcEwva + meta: + code: '## Current topic + + + Assuming that we extract the current topic as a slot on each dialog turn, + we can build a bar chart to see how various dialog topics are distributed. + The first of the two charts below aggregates the counts over dialog turns, + while the second one displays the distribution over time.' + height: 20 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-K0fThyfqJq + type: MARKDOWN + MARKDOWN-HncT4Y_WmV: + children: [] + id: MARKDOWN-HncT4Y_WmV + meta: + code: '## Flow visit ratio monitor + + + Thus chart aggregates the ratio of visits for each flow over the whole period + of service uptime. The aggregation period can be set to shorter time spans + using the filters on the left.' + height: 17 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-klrE6Idjlp + type: MARKDOWN + MARKDOWN-LyRuvHp-7m: + children: [] + id: MARKDOWN-LyRuvHp-7m + meta: + code: '## Weighted transition graph + + + The two weighted transition graphs emphasize the most frequently visited nodes + and transitions, effectively demonstrating the most popular routes inside + the dialog graph. + + + This can reveal characteristic features of user behavior given the current + dialog structure + + that call for changes. + + +
+ + ' + height: 24 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + - ROW-FMNDn-yXPC + type: MARKDOWN + MARKDOWN-NXluIKVHl5: + children: [] + id: MARKDOWN-NXluIKVHl5 + meta: + code: '# Annotations + + + Annotations are values that your conversational service derives from user + requests and stores in the `Context` object. They are produced by `PROCESSING` + functions and by some supplemental services in the `Pipeline`. + + + To make them available in the dashboard, you need to define a custom extractor + function for them (see `Extractor functions` tutorial for more information). + The output of that function will then be persisted to the `data` column of + the logs table, while the name of the function will be available in the `data + key` column. That makes it easy to filter the relevant log entries and use + them to build a Superset chart. + + + It''s important to keep in mind that `data` is a JSON column, which is why + you need to specify your own `custom sql` expression to get the relevant value. + + + ```sql + + JSON_VALUE(data, ''$.key.nested_key'') + + ``` + + + Additionally, you may need to cast the extracted string to a numeric datatype + like below to use certain aggregation functions. + + ```sql + + AVG(CAST(JSON_VALUE(data, ''$.key'') AS Int16)) + + ``` + + + **Note that the charts below will only display meaningful figures if the respective + annotation values have been collected. To get those, run the `sample data + provider` tutorial.**' + height: 63 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-efGgRzySlP + type: MARKDOWN + MARKDOWN-Ne7griq2wJ: + children: [] + id: MARKDOWN-Ne7griq2wJ + meta: + code: '## Node per dialog turn distribution + + + This bar chart aggregates node labels over dialog turns. Not only does this + show the average estimated dialog length, but it also allows you to observe + whether or not the path that users take on average deviates from the happy + path that you plan for the users. + + +
+ + ' + height: 24 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-tzfO7Zd-dD + type: MARKDOWN + MARKDOWN-OCNK7Q0hyn: + children: [] + id: MARKDOWN-OCNK7Q0hyn + meta: + code: "## Rating slot\n\nLet's assume that you have a service that extracts\ + \ ratings from user requests as a numeric variable. Much like the previous\ + \ example, you can employ a variety of charts to analyze this data, such as\ + \ line charts or box plots. \n\nNote that to reproduce the chart below the\ + \ value will have to be cast to Int16 or to some other numeric datatype to\ + \ find the average.\n\n```sql\nAVG(CAST(JSON_VALUE(data, '$.key') AS Int16))\n\ + ```" + height: 33 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + - ROW-Hcn9FCMH6a + type: MARKDOWN + MARKDOWN-PY70BXaRGq: + children: [] + id: MARKDOWN-PY70BXaRGq + meta: + code: "# Overview\n\nThe `overview` section is a generalized representation\ + \ of the data related to your service. It allows you to inspect raw data entries\ + \ or to observe some general trends using weighted charts based on the dialog\ + \ graph.\n\n## Raw data\n\nRaw data shows unaggregated data points as a table.\ + \ \nThe `data` column offers a closer view of the collected keys and labels\ + \ in the form of JSON objects.\n\n
\n" + height: 33 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + - ROW-R1SOLtdPpz + type: MARKDOWN + MARKDOWN-XuW-kEED70: + children: [] + id: MARKDOWN-XuW-kEED70 + meta: + code: '# Node statistics + + + The `Node statistics` section mostly contains data related to how frequently + individual nodes are visited with the aim of providing you insights on how + well distinct parts of the graph function. + + + ## Node visits distribution + + + The charts below display the number of times that the flows and nodes of the + dialog graph were visited during graph traversal. These statistics are supposed + to help the developers better understand the importance of any particular + node inside the graph.' + height: 35 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-t7PnH6oKHU + type: MARKDOWN + MARKDOWN-aXRTn3gE5x: + children: [] + id: MARKDOWN-aXRTn3gE5x + meta: + code: '## Transitions distribution + + + The chart below shows, how frequently each of the graph edges was traversed + by various users. + + + Based on this information, you can determine which transitions inside the + dialog graph function + + as intended. If some edge has never been traversed, it is safe to draw the + conclusion that transition + + conditions need to be adjusted.' + height: 24 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-y6AC1wLv1j + type: MARKDOWN + MARKDOWN-pmSRDxroDW: + children: [] + id: MARKDOWN-pmSRDxroDW + meta: + code: '## Terminal labels monitor + + + The following chart dynamically measures which nodes appear the most as a + finishing point in the dialog, e.g. what are the dialog turns, after which + the users quit the conversation. This chart is very useful, since it allows + you to trace potentially unwanted behavior and see if any of the bot messages + is discouraging users from further interaction.' + height: 21 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-j6eWWjqran + type: MARKDOWN + MARKDOWN-w66E2L3xdo: + children: [] + id: MARKDOWN-w66E2L3xdo + meta: + code: '## Node visit ratio monitor + + + Like the `Flow visit ratio monitor`, the node visit ratio monitor aggregates + node visits over time, showing the proportion of unique users visiting each + node of the graph at a given moment in time. For instance, this can demonstrate + how the dynamics of user load change after some changes are made to the graph, + e.g. nodes are added or deleted. The length of time spans can be regulated + using filters.' + height: 26 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-CBSQJNAfEV + type: MARKDOWN + MARKDOWN-zISK-3R8Ta: + children: [] + id: MARKDOWN-zISK-3R8Ta + meta: + code: '# Service statistics + + + This section contains charts that aggregate statistics over time, covering + the whole uptime of the service. They can be of big help, when the task is + to trace the changes in user behavior when new features or fixes are being + introduced. + + + ## Service users + + + This plot aggregates the count of unique users querying the DFF service at + any given point in time. The time periods to aggregate over can be changed + using the filter on the left. + + ' + height: 35 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + - ROW-zC6DVrW4wu + type: MARKDOWN + ROOT_ID: + children: + - GRID_ID + id: ROOT_ID + type: ROOT + ROW-7g6_n72hZ: + children: + - CHART-Af3zvLsiKV + id: ROW-7g6_n72hZ + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-Ae7v1prsp2: + children: + - CHART-mYC2udeF3a + id: ROW-Ae7v1prsp2 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-CBSQJNAfEV: + children: + - MARKDOWN-w66E2L3xdo + id: ROW-CBSQJNAfEV + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-Ccs1FbcI-: + children: + - CHART-explore-10-1 + - CHART-explore-13-1 + id: ROW-Ccs1FbcI- + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + type: ROW + ROW-EaYAQjv4W: + children: + - CHART-CuCYDOlGEu + id: ROW-EaYAQjv4W + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + type: ROW + ROW-FMNDn-yXPC: + children: + - MARKDOWN-LyRuvHp-7m + id: ROW-FMNDn-yXPC + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + type: ROW + ROW-Hcn9FCMH6a: + children: + - MARKDOWN-OCNK7Q0hyn + id: ROW-Hcn9FCMH6a + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-IsV-8cS3Z: + children: + - CHART-explore-16-1 + id: ROW-IsV-8cS3Z + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-K0fThyfqJq: + children: + - MARKDOWN-8Q9BhcEwva + id: ROW-K0fThyfqJq + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-LhKWfqM7V: + children: + - CHART-explore-22-1 + id: ROW-LhKWfqM7V + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-R1SOLtdPpz: + children: + - MARKDOWN-PY70BXaRGq + id: ROW-R1SOLtdPpz + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-JCU6rANFP + type: ROW + ROW-TZwRV0tZy: + children: + - CHART-explore-17-1 + id: ROW-TZwRV0tZy + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-UiCWq3ix1: + children: + - CHART-wci7CHiza6 + id: ROW-UiCWq3ix1 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-WirNNBBom: + children: + - CHART-DxY0c3RnIv + id: ROW-WirNNBBom + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-ZTVWOu2o0: + children: + - CHART-explore-21-1 + id: ROW-ZTVWOu2o0 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-efGgRzySlP: + children: + - MARKDOWN-NXluIKVHl5 + id: ROW-efGgRzySlP + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-hNOZdWZpw: + children: + - CHART-cxqeW2rGoV + id: ROW-hNOZdWZpw + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-j6eWWjqran: + children: + - MARKDOWN-pmSRDxroDW + id: ROW-j6eWWjqran + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-klrE6Idjlp: + children: + - MARKDOWN-HncT4Y_WmV + id: ROW-klrE6Idjlp + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + ROW-s_aeCbvt3: + children: + - CHART-explore-15-1 + id: ROW-s_aeCbvt3 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-q4CdGUDlq + type: ROW + ROW-t7PnH6oKHU: + children: + - MARKDOWN-XuW-kEED70 + id: ROW-t7PnH6oKHU + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-tzfO7Zd-dD: + children: + - MARKDOWN-Ne7griq2wJ + id: ROW-tzfO7Zd-dD + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-uSb7snkjI: + children: + - CHART-explore-9-1 + - CHART-explore-14-1 + id: ROW-uSb7snkjI + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-y6AC1wLv1j: + children: + - MARKDOWN-aXRTn3gE5x + id: ROW-y6AC1wLv1j + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-zC6DVrW4wu: + children: + - MARKDOWN-zISK-3R8Ta + id: ROW-zC6DVrW4wu + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-6zE8noCIsx + type: ROW + TAB-6zE8noCIsx: + children: + - ROW-zC6DVrW4wu + - ROW-Ae7v1prsp2 + - ROW-klrE6Idjlp + - ROW-ZTVWOu2o0 + - ROW-CBSQJNAfEV + - ROW-7g6_n72hZ + - ROW-j6eWWjqran + - ROW-LhKWfqM7V + id: TAB-6zE8noCIsx + meta: + defaultText: Tab title + placeholder: Tab title + text: Service statistics + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + type: TAB + TAB-Gw0Ffh1lG: + children: + - ROW-t7PnH6oKHU + - ROW-uSb7snkjI + - ROW-WirNNBBom + - ROW-y6AC1wLv1j + - ROW-UiCWq3ix1 + - ROW-tzfO7Zd-dD + - ROW-hNOZdWZpw + id: TAB-Gw0Ffh1lG + meta: + defaultText: Tab title + placeholder: Tab title + text: Node statistics + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + type: TAB + TAB-JCU6rANFP: + children: + - ROW-R1SOLtdPpz + - ROW-EaYAQjv4W + - ROW-FMNDn-yXPC + - ROW-Ccs1FbcI- + id: TAB-JCU6rANFP + meta: + defaultText: Tab title + placeholder: Tab title + text: Overview + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + type: TAB + TAB-q4CdGUDlq: + children: + - ROW-efGgRzySlP + - ROW-K0fThyfqJq + - ROW-IsV-8cS3Z + - ROW-s_aeCbvt3 + - ROW-Hcn9FCMH6a + - ROW-TZwRV0tZy + id: TAB-q4CdGUDlq + meta: + defaultText: Tab title + placeholder: Tab title + text: Annotations + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + type: TAB + TABS-Xoi5oUBxZI: + children: + - TAB-JCU6rANFP + - TAB-Gw0Ffh1lG + - TAB-6zE8noCIsx + - TAB-q4CdGUDlq + id: TABS-Xoi5oUBxZI + meta: {} + parents: + - ROOT_ID + - GRID_ID + type: TABS +metadata: + color_scheme: echarts4Colors + label_colors: {} + shared_label_colors: + '0': '#c23531' + '1': '#2f4554' + '2': '#546570' + '3': '#c4ccd3' + '4': '#c23531' + '5': '#2f4554' + '6': '#61a0a8' + '7': '#d48265' + '8': '#91c7ae' + '9': '#749f83' + '10': '#61a0a8' + '11': '#d48265' + '12': '#91c7ae' + '13': '#749f83' + '14': '#ca8622' + '15': '#bda29a' + '16': '#6e7074' + animals: '#c23531' + news: '#2f4554' + root: '#61a0a8' + small_talk: '#d48265' + animals, ask_about_breed: '#c23531' + animals, ask_about_color: '#2f4554' + animals, what_animal: '#61a0a8' + news, ask_about_science: '#d48265' + news, science_news: '#91c7ae' + news, what_news: '#749f83' + root, fallback: '#ca8622' + small_talk, ask_talk_about: '#bda29a' + animals, ask_about_training: '#61a0a8' + animals, have_pets: '#d48265' + animals, like_animals: '#91c7ae' + animals, tell_fact_about_breed: '#749f83' + news, ask_about_sport: '#6e7074' + news, sport_news: '#c4ccd3' + small_talk, ask_some_questions: '#61a0a8' + AVG(CAST(JSON_VALUE(data, '$.rating') AS...: '#c23531' + books: '#c23531' + films: '#2f4554' + games: '#61a0a8' + smalltalk: '#d48265' + 'news: what_news': '#c23531' + 'small_talk: ask_talk_about': '#2f4554' + 'animals: tell_fact_about_breed': '#61a0a8' + 'news: sport_news': '#d48265' + 'animals: have_pets': '#91c7ae' + 'animals: ask_about_color': '#749f83' + 'small_talk: ask_some_questions': '#ca8622' + 'animals: what_animal': '#bda29a' + 'animals: ask_about_breed': '#6e7074' + 'root: fallback': '#546570' + 'news: science_news': '#c4ccd3' + 'animals: like_animals': '#c23531' + 'news: ask_about_science': '#2f4554' + 'animals: ask_about_training': '#61a0a8' + 'news: ask_about_sport': '#6e7074' + fallback: '#2f4554' + ask_about_breed: '#d48265' + what_animal: '#91c7ae' + ask_about_color: '#749f83' + tell_fact_about_breed: '#ca8622' + like_animals: '#bda29a' + ask_about_training: '#6e7074' + have_pets: '#546570' + sport_news: '#c23531' + what_news: '#2f4554' + science_news: '#61a0a8' + ask_about_science: '#d48265' + ask_about_sport: '#91c7ae' + ask_some_questions: '#ca8622' + ask_talk_about: '#bda29a' + timed_refresh_immune_slices: [] + expanded_slices: {} + refresh_frequency: 1800 + show_native_filters: true + default_filters: '{}' + chart_configuration: {} + color_scheme_domain: + - '#c23531' + - '#2f4554' + - '#61a0a8' + - '#d48265' + - '#91c7ae' + - '#749f83' + - '#ca8622' + - '#bda29a' + - '#6e7074' + - '#546570' + - '#c4ccd3' + cross_filters_enabled: false + native_filter_configuration: + - id: NATIVE_FILTER-5vyW3SgU5 + controlValues: + enableEmptyFilter: false + name: Time grain + filterType: filter_timegrain + targets: + - datasetUuid: fda98ab8-f550-45f1-9ded-0113f3e67260 + defaultDataMask: + extraFormData: + time_grain_sqla: PT1M + filterState: + label: Minute + value: + - PT1M + cascadeParentIds: [] + scope: + rootPath: + - TAB-6zE8noCIsx + excluded: + - 10 + type: NATIVE_FILTER + description: '' + chartsInScope: + - 2 + - 4 + - 7 + - 13 + tabsInScope: + - TAB-6zE8noCIsx + - id: NATIVE_FILTER-k81Ybg31L + controlValues: + enableEmptyFilter: false + name: Time range + filterType: filter_time + targets: + - {} + defaultDataMask: + extraFormData: + time_range: 'DATEADD(DATETIME("now"), -1, day) : now' + filterState: + value: 'DATEADD(DATETIME("now"), -1, day) : now' + cascadeParentIds: [] + scope: + rootPath: + - TAB-6zE8noCIsx + excluded: + - 7 + type: NATIVE_FILTER + description: '' + chartsInScope: + - 1 + - 2 + - 3 + - 4 + - 6 + - 8 + - 9 + - 10 + - 12 + - 13 + - 14 + tabsInScope: + - TAB-6zE8noCIsx + - TAB-Gw0Ffh1lG + - TAB-JCU6rANFP + - id: NATIVE_FILTER-Q_v9J5gqV + controlValues: + enableEmptyFilter: false + defaultToFirstItem: false + multiSelect: true + searchAllOptions: false + inverseSelection: false + name: History + filterType: filter_select + targets: + - column: + name: request_id + datasetUuid: d7f6546e-1e3a-479d-8531-05b5e73e5c05 + defaultDataMask: + extraFormData: {} + filterState: {} + ownState: {} + cascadeParentIds: [] + scope: + rootPath: + - TAB-Gw0Ffh1lG + excluded: [] + type: NATIVE_FILTER + description: '' + chartsInScope: + - 1 + - 3 + - 6 + - 9 + - 10 + tabsInScope: + - TAB-Gw0Ffh1lG + - id: NATIVE_FILTER-EGnz5obeE + controlValues: + enableEmptyFilter: false + defaultToFirstItem: false + multiSelect: true + searchAllOptions: false + inverseSelection: false + name: User id + filterType: filter_select + targets: + - column: + name: context_id + datasetUuid: fda98ab8-f550-45f1-9ded-0113f3e67260 + defaultDataMask: + extraFormData: {} + filterState: {} + ownState: {} + cascadeParentIds: [] + scope: + rootPath: + - TAB-Gw0Ffh1lG + - TAB-q4CdGUDlq + - TAB-JCU6rANFP + excluded: [] + type: NATIVE_FILTER + description: '' + chartsInScope: + - 1 + - 3 + - 6 + - 8 + - 9 + - 10 + - 12 + - 14 + - 15 + - 16 + - 17 + tabsInScope: + - TAB-Gw0Ffh1lG + - TAB-JCU6rANFP + - TAB-q4CdGUDlq + stagger_refresh: true +version: 1.0.0 diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index 5ddab7c69..b696524ca 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -7,15 +7,14 @@ cache_timeout: null schema: test sql: "\nWITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id']\ \ as context_id,\n otel_logs.LogAttributes['request_id'] as request_id,\n \ - \ otel_traces.Timestamp as start_time,\n otel_traces.SpanName as data_key,\n\ - \ otel_logs.Body as data,\n JSON_VALUE(otel_logs.Body, '$.label') as label,\n\ - \ JSON_VALUE(otel_logs.Body, '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body,\ + \ toDateTime(otel_traces.Timestamp) as start_time,\n otel_traces.SpanName as\ + \ data_key,\n otel_logs.Body as data,\n JSON_VALUE(otel_logs.Body, '$.label')\ + \ as label,\n JSON_VALUE(otel_logs.Body, '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body,\ \ '$.node') as node_label,\n otel_logs.TraceId as trace_id,\n otel_traces.TraceId\n\ - FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId and\ - \ otel_traces.SpanName = 'get_current_label'\n ORDER BY context_id, request_id\n\ - ) SELECT context_id,\n request_id,\n start_time,\n data_key,\n data,\n\ - \ label,\n neighbor(label, -1) as prev_label,\n flow_label,\n node_label\n\ - FROM main\nWHERE label != ''\n" + FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId\n\ + \ ORDER BY context_id, request_id\n) SELECT context_id,\n request_id,\n \ + \ start_time,\n data_key,\n data,\n label,\n neighbor(label, -1) as\ + \ prev_label,\n flow_label,\n node_label\nFROM main\n" params: null template_params: null filter_select_enabled: false diff --git a/dff/config/superset_dashboard/metadata.yaml b/dff/config/superset_dashboard/metadata.yaml index b68dadba1..c4d2fb8ed 100644 --- a/dff/config/superset_dashboard/metadata.yaml +++ b/dff/config/superset_dashboard/metadata.yaml @@ -1,3 +1,3 @@ version: 1.0.0 type: Dashboard -timestamp: '2023-07-25T14:27:32.324677+00:00' +timestamp: '2023-09-14T12:24:44.253388+00:00' diff --git a/dff/stats/instrumentor.py b/dff/stats/instrumentor.py index a053c532b..88e5125df 100644 --- a/dff/stats/instrumentor.py +++ b/dff/stats/instrumentor.py @@ -62,7 +62,7 @@ class OtelInstrumentor(BaseInstrumentor): .. code-block:: @dff_instrumentor - def function(context, pipeline, runtime_info): + async def function(context, pipeline, runtime_info): ... :param logger_provider: Opentelemetry logger provider. Used to construct a logger instance. diff --git a/dff/utils/testing/toy_script.py b/dff/utils/testing/toy_script.py index 78a3f0fb1..811ef2fa4 100644 --- a/dff/utils/testing/toy_script.py +++ b/dff/utils/testing/toy_script.py @@ -62,3 +62,143 @@ :meta hide-value: """ + +MULTIFLOW_SCRIPT = { + "root": { + "start": { + RESPONSE: Message(text="Hi"), + TRANSITIONS: { + ("small_talk", "ask_some_questions"): exact_match(Message(text="hi")), + ("animals", "have_pets"): exact_match(Message(text="i like animals")), + ("animals", "like_animals"): exact_match(Message(text="let's talk about animals")), + ("news", "what_news"): exact_match(Message(text="let's talk about news")), + }, + }, + "fallback": {RESPONSE: Message(text="Oops")}, + }, + "animals": { + "have_pets": { + RESPONSE: Message(text="do you have pets?"), + TRANSITIONS: {"what_animal": exact_match(Message(text="yes"))}, + }, + "like_animals": { + RESPONSE: Message(text="do you like it?"), + TRANSITIONS: {"what_animal": exact_match(Message(text="yes"))}, + }, + "what_animal": { + RESPONSE: Message(text="what animals do you have?"), + TRANSITIONS: { + "ask_about_color": exact_match(Message(text="bird")), + "ask_about_breed": exact_match(Message(text="dog")), + }, + }, + "ask_about_color": {RESPONSE: Message(text="what color is it")}, + "ask_about_breed": { + RESPONSE: Message(text="what is this breed?"), + TRANSITIONS: { + "ask_about_breed": exact_match(Message(text="pereat")), + "tell_fact_about_breed": exact_match(Message(text="bulldog")), + "ask_about_training": exact_match(Message(text="i do not known")), + }, + }, + "tell_fact_about_breed": { + RESPONSE: Message(text="Bulldogs appeared in England as specialized bull-baiting dogs. "), + }, + "ask_about_training": {RESPONSE: Message(text="Do you train your dog? ")}, + }, + "news": { + "what_news": { + RESPONSE: Message(text="what kind of news do you prefer?"), + TRANSITIONS: { + "ask_about_science": exact_match(Message(text="science")), + "ask_about_sport": exact_match(Message(text="sport")), + }, + }, + "ask_about_science": { + RESPONSE: Message(text="i got news about science, do you want to hear?"), + TRANSITIONS: { + "science_news": exact_match(Message(text="yes")), + ("small_talk", "ask_some_questions"): exact_match(Message(text="let's change the topic")), + }, + }, + "science_news": { + RESPONSE: Message(text="This is science news"), + TRANSITIONS: { + "what_news": exact_match(Message(text="ok")), + ("small_talk", "ask_some_questions"): exact_match(Message(text="let's change the topic")), + }, + }, + "ask_about_sport": { + RESPONSE: Message(text="i got news about sport, do you want to hear?"), + TRANSITIONS: { + "sport_news": exact_match(Message(text="yes")), + ("small_talk", "ask_some_questions"): exact_match(Message(text="let's change the topic")), + }, + }, + "sport_news": { + RESPONSE: Message(text="This is sport news"), + TRANSITIONS: { + "what_news": exact_match(Message(text="ok")), + ("small_talk", "ask_some_questions"): exact_match(Message(text="let's change the topic")), + }, + }, + }, + "small_talk": { + "ask_some_questions": { + RESPONSE: Message(text="how are you"), + TRANSITIONS: { + "ask_talk_about": exact_match(Message(text="fine")), + ("animals", "like_animals"): exact_match(Message(text="let's talk about animals")), + ("news", "what_news"): exact_match(Message(text="let's talk about news")), + }, + }, + "ask_talk_about": { + RESPONSE: Message(text="what do you want to talk about"), + TRANSITIONS: { + ("animals", "like_animals"): exact_match(Message(text="dog")), + ("news", "what_news"): exact_match(Message(text="let's talk about news")), + }, + }, + }, +} +""" +Simple dialog with multiple flows. + +:meta hide-value: +""" + +MULTIFLOW_REQUEST_OPTIONS = { + "root": { + "start": [ + "hi", + "i like animals", + "let's talk about animals", + ] + }, + "animals": { + "have_pets": ["yes"], + "like_animals": ["yes"], + "what_animal": ["bird", "dog"], + "ask_about_breed": ["pereat", "bulldog", "i do not known"], + }, + "news": { + "what_news": ["science", "sport"], + "ask_about_science": ["yes", "let's change the topic"], + "science_news": ["ok", "let's change the topic"], + "ask_about_sport": ["yes", "let's change the topic"], + "sport_news": ["ok", "let's change the topic"], + }, + "small_talk": { + "ask_some_questions": [ + "fine", + "let's talk about animals", + "let's talk about news", + ], + "ask_talk_about": ["dog", "let's talk about news"], + }, +} +""" +Request options for automated client requests. + +:meta hide-value: +""" diff --git a/tests/stats/test_main.py b/tests/stats/test_main.py index ac72fbf9b..279565558 100644 --- a/tests/stats/test_main.py +++ b/tests/stats/test_main.py @@ -52,14 +52,17 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): dashboard_res = session.get(dashboard_url, headers=headers) assert dashboard_res.status_code == 200 dashboard_json = dashboard_res.json() + print(dashboard_json["result"]["charts"]) assert sorted(dashboard_json["result"]["charts"]) == [ + "Current topic [time series bar chart]", + "Current topic slot [bar chart]", "Flow visit ratio monitor", "Node Visits", "Node counts", "Node visit ratio monitor", - "Node visits [cloud]", "Node visits [ratio]", "Node visits [sunburst]", + "Rating slot [line chart]", "Service load [users]", "Table", "Terminal labels", @@ -68,7 +71,7 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): "Transition ratio [chord]", ] assert dashboard_json["result"]["url"] == "/superset/dashboard/dff-stats/" - assert dashboard_json["result"]["dashboard_title"] == "DFF Stats" + assert dashboard_json["result"]["dashboard_title"] == "DFF statistics dashboard" datasets_result = session.get(datasets_url, headers=headers) datasets_json = datasets_result.json() assert datasets_json["count"] == 2 @@ -80,8 +83,8 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): ] charts_result = session.get(charts_url, headers=headers) charts_json = charts_result.json() - assert charts_json["count"] == 14 - assert sorted(charts_json["ids"]) == list(range(1, 15)) + assert charts_json["count"] == 15 + assert sorted(charts_json["ids"]) == list(range(1, 16)) session.close() diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py index 2dd4bb76c..d3a7f87da 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/tutorials/stats/3_sample_data_provider.py @@ -1,167 +1,66 @@ +# %% [markdown] +""" +# 3. Sample data provider + +This script provides data for the dashboard emulating simultaneous queries +to the service by multiple users. + +""" + +# %pip install dff[stats] + +# %% import random import asyncio from tqdm import tqdm -from dff.script import RESPONSE, TRANSITIONS, Context, Message -from dff.script import conditions as cnd -from dff.pipeline import Pipeline, Service, ACTOR +from dff.script import Context, Message +from dff.pipeline import Pipeline, Service, ACTOR, ExtraHandlerRuntimeInfo from dff.stats import ( default_extractors, OtelInstrumentor, ) +from dff.utils.testing import is_interactive_mode +from dff.utils.testing.toy_script import MULTIFLOW_SCRIPT, MULTIFLOW_REQUEST_OPTIONS +# %% +# instrumentation code dff_instrumentor = OtelInstrumentor.from_url("grpc://localhost:4317", insecure=True) dff_instrumentor.instrument() -transitions = { - "root": { - "start": [ - "hi", - "i like animals", - "let's talk about animals", - ] - }, - "animals": { - "have_pets": ["yes"], - "like_animals": ["yes"], - "what_animal": ["bird", "dog"], - "ask_about_breed": ["pereat", "bulldog", "i do not known"], - }, - "news": { - "what_news": ["science", "sport"], - "ask_about_science": ["yes", "let's change the topic"], - "science_news": ["ok", "let's change the topic"], - "ask_about_sport": ["yes", "let's change the topic"], - "sport_news": ["ok", "let's change the topic"], - }, - "small_talk": { - "ask_some_questions": [ - "fine", - "let's talk about animals", - "let's talk about news", - ], - "ask_talk_about": ["dog", "let's talk about news"], - }, -} -# a dialog script -script = { - "root": { - "start": { - RESPONSE: Message(text="Hi"), - TRANSITIONS: { - ("small_talk", "ask_some_questions"): cnd.exact_match(Message(text="hi")), - ("animals", "have_pets"): cnd.exact_match(Message(text="i like animals")), - ("animals", "like_animals"): cnd.exact_match( - Message(text="let's talk about animals") - ), - ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), - }, - }, - "fallback": {RESPONSE: Message(text="Oops")}, - }, - "animals": { - "have_pets": { - RESPONSE: Message(text="do you have pets?"), - TRANSITIONS: {"what_animal": cnd.exact_match(Message(text="yes"))}, - }, - "like_animals": { - RESPONSE: Message(text="do you like it?"), - TRANSITIONS: {"what_animal": cnd.exact_match(Message(text="yes"))}, - }, - "what_animal": { - RESPONSE: Message(text="what animals do you have?"), - TRANSITIONS: { - "ask_about_color": cnd.exact_match(Message(text="bird")), - "ask_about_breed": cnd.exact_match(Message(text="dog")), - }, - }, - "ask_about_color": {RESPONSE: Message(text="what color is it")}, - "ask_about_breed": { - RESPONSE: Message(text="what is this breed?"), - TRANSITIONS: { - "ask_about_breed": cnd.exact_match(Message(text="pereat")), - "tell_fact_about_breed": cnd.exact_match(Message(text="bulldog")), - "ask_about_training": cnd.exact_match(Message(text="i do not known")), - }, - }, - "tell_fact_about_breed": { - RESPONSE: Message( - text="Bulldogs appeared in England as specialized bull-baiting dogs. " - ), - }, - "ask_about_training": {RESPONSE: Message(text="Do you train your dog? ")}, - }, - "news": { - "what_news": { - RESPONSE: Message(text="what kind of news do you prefer?"), - TRANSITIONS: { - "ask_about_science": cnd.exact_match(Message(text="science")), - "ask_about_sport": cnd.exact_match(Message(text="sport")), - }, - }, - "ask_about_science": { - RESPONSE: Message(text="i got news about science, do you want to hear?"), - TRANSITIONS: { - "science_news": cnd.exact_match(Message(text="yes")), - ("small_talk", "ask_some_questions"): cnd.exact_match( - Message(text="let's change the topic") - ), - }, - }, - "science_news": { - RESPONSE: Message(text="This is science news"), - TRANSITIONS: { - "what_news": cnd.exact_match(Message(text="ok")), - ("small_talk", "ask_some_questions"): cnd.exact_match( - Message(text="let's change the topic") - ), - }, - }, - "ask_about_sport": { - RESPONSE: Message(text="i got news about sport, do you want to hear?"), - TRANSITIONS: { - "sport_news": cnd.exact_match(Message(text="yes")), - ("small_talk", "ask_some_questions"): cnd.exact_match( - Message(text="let's change the topic") - ), - }, - }, - "sport_news": { - RESPONSE: Message(text="This is sport news"), - TRANSITIONS: { - "what_news": cnd.exact_match(Message(text="ok")), - ("small_talk", "ask_some_questions"): cnd.exact_match( - Message(text="let's change the topic") - ), - }, - }, - }, - "small_talk": { - "ask_some_questions": { - RESPONSE: Message(text="how are you"), - TRANSITIONS: { - "ask_talk_about": cnd.exact_match(Message(text="fine")), - ("animals", "like_animals"): cnd.exact_match( - Message(text="let's talk about animals") - ), - ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), - }, - }, - "ask_talk_about": { - RESPONSE: Message(text="what do you want to talk about"), - TRANSITIONS: { - ("animals", "like_animals"): cnd.exact_match(Message(text="dog")), - ("news", "what_news"): cnd.exact_match(Message(text="let's talk about news")), - }, - }, - }, -} +def slot_processor_1(ctx: Context): + ctx.misc["slots"] = {"rating": random.randint(1, 10)} + + +def slot_processor_2(ctx: Context): + ctx.misc["slots"] = {"current_topic": random.choice(["films", "games", "books", "smalltalk"])} + + +@dff_instrumentor +async def get_slots(ctx: Context, _, info: ExtraHandlerRuntimeInfo): + return ctx.misc["slots"] + + +def confidence_processor(ctx: Context): + ctx.framework_states["response_confidence"] = random.random() + + +@dff_instrumentor +async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): + data = {"response_confidence": ctx.framework_states["response_confidence"]} + return data + + +# %% pipeline = Pipeline.from_dict( { - "script": script, + "script": MULTIFLOW_SCRIPT, "start_label": ("root", "start"), "fallback_label": ("root", "fallback"), "components": [ + Service(slot_processor_1, after_handler=[get_slots]), + Service(slot_processor_2, after_handler=[get_slots]), + Service(confidence_processor, after_handler=[get_confidence]), Service( handler=ACTOR, before_handler=[default_extractors.get_timing_before], @@ -175,14 +74,22 @@ ) +# %% async def worker(queue: asyncio.Queue): + """ + Worker function for dispatching one client message. + + :param queue: Queue for sharing context variables. + """ ctx: Context = await queue.get() label = ctx.last_label if ctx.last_label else pipeline.actor.fallback_label flow, node = label[:2] if [flow, node] == ["root", "fallback"]: + rand_interval = float(random.randint(0, 1)) + random.random() + await asyncio.sleep(rand_interval) ctx = Context() flow, node = ["root", "start"] - answers = list(transitions.get(flow, {}).get(node, [])) + answers = list(MULTIFLOW_REQUEST_OPTIONS.get(flow, {}).get(node, [])) in_text = random.choice(answers) if answers else "go to fallback" in_message = Message(text=in_text) rand_interval = float(random.randint(0, 1)) + random.random() @@ -193,13 +100,23 @@ async def worker(queue: asyncio.Queue): await queue.put(ctx) -async def main(n_iterations: int = 25): +# %% +# main loop +async def main(n_iterations: int = 100, n_workers: int = 4): + """ + Main loop that runs one or more worker coroutines in parallel. + + :param n_iterations: Total number of coroutine runs. + :param n_workers: Number of parallelized coroutine runs. + """ ctxs = asyncio.Queue() - for _ in range(4): + parallel_iterations = n_iterations // n_workers + for _ in range(n_workers): await ctxs.put(Context()) - for _ in tqdm(range(n_iterations)): - await asyncio.gather(*(worker(ctxs) for _ in range(4))) + for _ in tqdm(range(parallel_iterations)): + await asyncio.gather(*(worker(ctxs) for _ in range(n_workers))) if __name__ == "__main__": - asyncio.run(main()) + if is_interactive_mode(): + asyncio.run(main()) From 97b67c3b0857b85a958637672f10bce72ccaeaa4 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 15 Sep 2023 12:18:57 +0300 Subject: [PATCH 09/46] Add extractors for requests and responses as default instrumentors --- dff/stats/default_extractors.py | 25 +++++++++++++++++++++++ dff/stats/instrumentor.py | 10 ++++----- tutorials/stats/3_sample_data_provider.py | 5 ++++- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/dff/stats/default_extractors.py b/dff/stats/default_extractors.py index d48cd6d26..8ffe4a049 100644 --- a/dff/stats/default_extractors.py +++ b/dff/stats/default_extractors.py @@ -53,3 +53,28 @@ async def get_timing_after(ctx: Context, _, info: ExtraHandlerRuntimeInfo): # n start_time = ctx.framework_states[get_wrapper_field(info, "time")] data = {"execution_time": str(datetime.now() - start_time)} return data + + +async def get_last_response(ctx: Context, _, info: ExtraHandlerRuntimeInfo): + """ + Extract the last response in the current context. + This handler is best used together with the `ACTOR` component. + + This function is required to enable charts that aggregate requests and responses. + """ + data = {"last_response": ctx.last_response} + return data + + +async def get_last_request(ctx: Context, _, info: ExtraHandlerRuntimeInfo): + """ + Extract the last request in the current context. + This handler is best used together with the `ACTOR` component. + + This function is required to enable charts that aggregate requests and responses. + """ + data = {"last_request": ctx.last_request} + return data + + +__all__ = [get_current_label, get_timing_before, get_timing_after, get_last_request, get_last_response] diff --git a/dff/stats/instrumentor.py b/dff/stats/instrumentor.py index 88e5125df..d5f341624 100644 --- a/dff/stats/instrumentor.py +++ b/dff/stats/instrumentor.py @@ -126,14 +126,12 @@ def _instrument(self, logger_provider=None, tracer_provider=None, meter_provider self._configure_providers( logger_provider=logger_provider, tracer_provider=tracer_provider, meter_provider=meter_provider ) - wrap_function_wrapper(default_extractors, "get_current_label", self.__call__.__wrapped__) - wrap_function_wrapper(default_extractors, "get_timing_before", self.__call__.__wrapped__) - wrap_function_wrapper(default_extractors, "get_timing_after", self.__call__.__wrapped__) + for func_name in [func.__name__ for func in default_extractors.__all__]: + wrap_function_wrapper(default_extractors, func_name, self.__call__.__wrapped__) def _uninstrument(self, **kwargs): - unwrap(default_extractors, "get_current_label") - unwrap(default_extractors, "get_timing_before") - unwrap(default_extractors, "get_timing_after") + for func_name in [func.__name__ for func in default_extractors.__all__]: + unwrap(default_extractors, func_name) def _configure_providers(self, logger_provider, tracer_provider, meter_provider): self._logger_provider = logger_provider or get_logger_provider() diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py index d3a7f87da..03ebe1345 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/tutorials/stats/3_sample_data_provider.py @@ -2,7 +2,8 @@ """ # 3. Sample data provider -This script provides data for the dashboard emulating simultaneous queries +This script demonstrates various instrumentation capabilities. +It also provides data for the dashboard emulating simultaneous queries to the service by multiple users. """ @@ -67,6 +68,8 @@ async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): after_handler=[ default_extractors.get_timing_after, default_extractors.get_current_label, + default_extractors.get_last_request, + default_extractors.get_last_response, ], ), ], From c180182ed8be56d805a1b81df3b585852b09711f Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 15 Sep 2023 15:44:25 +0300 Subject: [PATCH 10/46] add 'get_last_request', 'get_last_response'; add charts for requests and responses; update test --- ...ml => Current_topic_slot_bar_chart_4.yaml} | 0 ...urrent_topic_time_series_bar_chart_2.yaml} | 0 ...{Node_Visits_6.yaml => Node_Visits_7.yaml} | 0 ...{Node_counts_9.yaml => Node_counts_3.yaml} | 0 ...2.yaml => Node_visit_ratio_monitor_8.yaml} | 0 ..._ratio_3.yaml => Node_visits_ratio_6.yaml} | 0 ...st_10.yaml => Node_visits_sunburst_5.yaml} | 0 ..._17.yaml => Rating_slot_line_chart_1.yaml} | 0 .../charts/Requests_17.yaml | 51 +++++ .../charts/Responses_16.yaml | 51 +++++ ...users_4.yaml => Service_load_users_9.yaml} | 0 ..._labels_7.yaml => Terminal_labels_15.yaml} | 0 ...ounts_1.yaml => Transition_counts_12.yaml} | 0 ...ayout_8.yaml => Transition_layout_10.yaml} | 0 ...12.yaml => Transition_ratio_chord_11.yaml} | 0 .../DFF_statistics_dashboard_1.yaml | 198 +++++++++++++----- dff/config/superset_dashboard/metadata.yaml | 2 +- dff/stats/cli.py | 3 +- dff/stats/default_extractors.py | 8 +- tests/stats/test_main.py | 6 +- 20 files changed, 263 insertions(+), 56 deletions(-) rename dff/config/superset_dashboard/charts/{Current_topic_slot_bar_chart_16.yaml => Current_topic_slot_bar_chart_4.yaml} (100%) rename dff/config/superset_dashboard/charts/{Current_topic_time_series_bar_chart_15.yaml => Current_topic_time_series_bar_chart_2.yaml} (100%) rename dff/config/superset_dashboard/charts/{Node_Visits_6.yaml => Node_Visits_7.yaml} (100%) rename dff/config/superset_dashboard/charts/{Node_counts_9.yaml => Node_counts_3.yaml} (100%) rename dff/config/superset_dashboard/charts/{Node_visit_ratio_monitor_2.yaml => Node_visit_ratio_monitor_8.yaml} (100%) rename dff/config/superset_dashboard/charts/{Node_visits_ratio_3.yaml => Node_visits_ratio_6.yaml} (100%) rename dff/config/superset_dashboard/charts/{Node_visits_sunburst_10.yaml => Node_visits_sunburst_5.yaml} (100%) rename dff/config/superset_dashboard/charts/{Rating_slot_line_chart_17.yaml => Rating_slot_line_chart_1.yaml} (100%) create mode 100644 dff/config/superset_dashboard/charts/Requests_17.yaml create mode 100644 dff/config/superset_dashboard/charts/Responses_16.yaml rename dff/config/superset_dashboard/charts/{Service_load_users_4.yaml => Service_load_users_9.yaml} (100%) rename dff/config/superset_dashboard/charts/{Terminal_labels_7.yaml => Terminal_labels_15.yaml} (100%) rename dff/config/superset_dashboard/charts/{Transition_counts_1.yaml => Transition_counts_12.yaml} (100%) rename dff/config/superset_dashboard/charts/{Transition_layout_8.yaml => Transition_layout_10.yaml} (100%) rename dff/config/superset_dashboard/charts/{Transition_ratio_chord_12.yaml => Transition_ratio_chord_11.yaml} (100%) diff --git a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_16.yaml rename to dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml diff --git a/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml b/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_15.yaml rename to dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml diff --git a/dff/config/superset_dashboard/charts/Node_Visits_6.yaml b/dff/config/superset_dashboard/charts/Node_Visits_7.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Node_Visits_6.yaml rename to dff/config/superset_dashboard/charts/Node_Visits_7.yaml diff --git a/dff/config/superset_dashboard/charts/Node_counts_9.yaml b/dff/config/superset_dashboard/charts/Node_counts_3.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Node_counts_9.yaml rename to dff/config/superset_dashboard/charts/Node_counts_3.yaml diff --git a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_2.yaml rename to dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml diff --git a/dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml b/dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Node_visits_ratio_3.yaml rename to dff/config/superset_dashboard/charts/Node_visits_ratio_6.yaml diff --git a/dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml b/dff/config/superset_dashboard/charts/Node_visits_sunburst_5.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Node_visits_sunburst_10.yaml rename to dff/config/superset_dashboard/charts/Node_visits_sunburst_5.yaml diff --git a/dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml b/dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Rating_slot_line_chart_17.yaml rename to dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml diff --git a/dff/config/superset_dashboard/charts/Requests_17.yaml b/dff/config/superset_dashboard/charts/Requests_17.yaml new file mode 100644 index 000000000..f6cadd058 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Requests_17.yaml @@ -0,0 +1,51 @@ +slice_name: Requests +description: null +certified_by: null +certification_details: null +viz_type: table +params: + datasource: 2__table + viz_type: table + granularity_sqla: start_time + time_grain_sqla: P1D + time_range: No filter + query_mode: raw + groupby: [] + all_columns: + - context_id + - request_id + - start_time + - label: data + sqlExpression: JSON_VALUE(data, '$.last_request') + expressionType: SQL + percent_metrics: [] + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_last_request + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_4amlkzz0hd3_exx83iz5rof + order_by_cols: [] + row_limit: 1000 + server_page_length: 10 + order_desc: true + table_timestamp_format: smart_date + show_cell_bars: true + color_pn: true + extra_form_data: {} + dashboards: [] +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_request"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_request'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No + filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 45ef67db-d33d-49f5-8d46-1f0fa518eaac +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Responses_16.yaml b/dff/config/superset_dashboard/charts/Responses_16.yaml new file mode 100644 index 000000000..a4f8d5df2 --- /dev/null +++ b/dff/config/superset_dashboard/charts/Responses_16.yaml @@ -0,0 +1,51 @@ +slice_name: Responses +description: null +certified_by: null +certification_details: null +viz_type: table +params: + datasource: 2__table + viz_type: table + granularity_sqla: start_time + time_grain_sqla: P1D + time_range: No filter + query_mode: raw + groupby: [] + all_columns: + - context_id + - request_id + - start_time + - label: data + sqlExpression: JSON_VALUE(data, '$.last_response') + expressionType: SQL + percent_metrics: [] + adhoc_filters: + - expressionType: SIMPLE + subject: data_key + operator: == + operatorId: EQUALS + comparator: get_last_response + clause: WHERE + sqlExpression: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_m3nzyr545di_lxjaivcal1 + order_by_cols: [] + row_limit: 1000 + server_page_length: 10 + order_desc: true + table_timestamp_format: smart_date + show_cell_bars: true + color_pn: true + extra_form_data: {} + dashboards: [] +query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_response"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_response'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No + filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' +cache_timeout: null +uuid: 7844eb6d-4fce-44cf-8994-fb61a221a2ab +version: 1.0.0 +dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 diff --git a/dff/config/superset_dashboard/charts/Service_load_users_4.yaml b/dff/config/superset_dashboard/charts/Service_load_users_9.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Service_load_users_4.yaml rename to dff/config/superset_dashboard/charts/Service_load_users_9.yaml diff --git a/dff/config/superset_dashboard/charts/Terminal_labels_7.yaml b/dff/config/superset_dashboard/charts/Terminal_labels_15.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Terminal_labels_7.yaml rename to dff/config/superset_dashboard/charts/Terminal_labels_15.yaml diff --git a/dff/config/superset_dashboard/charts/Transition_counts_1.yaml b/dff/config/superset_dashboard/charts/Transition_counts_12.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Transition_counts_1.yaml rename to dff/config/superset_dashboard/charts/Transition_counts_12.yaml diff --git a/dff/config/superset_dashboard/charts/Transition_layout_8.yaml b/dff/config/superset_dashboard/charts/Transition_layout_10.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Transition_layout_8.yaml rename to dff/config/superset_dashboard/charts/Transition_layout_10.yaml diff --git a/dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml b/dff/config/superset_dashboard/charts/Transition_ratio_chord_11.yaml similarity index 100% rename from dff/config/superset_dashboard/charts/Transition_ratio_chord_12.yaml rename to dff/config/superset_dashboard/charts/Transition_ratio_chord_11.yaml diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 895715768..2556d6e9f 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -4,11 +4,27 @@ css: '' slug: dff-stats uuid: 68bce374-99bc-4890-b8c2-cb172409b894 position: + CHART-91whs_IaiF: + children: [] + id: CHART-91whs_IaiF + meta: + chartId: 17 + height: 50 + sliceName: Requests + uuid: 45ef67db-d33d-49f5-8d46-1f0fa518eaac + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-oXaTD35jB + type: CHART CHART-Af3zvLsiKV: children: [] id: CHART-Af3zvLsiKV meta: - chartId: 2 + chartId: 8 height: 66 sliceName: Node visit ratio monitor uuid: 6fafe59c-0fec-4cd8-a8b3-c0bfaffb2135 @@ -41,7 +57,7 @@ position: children: [] id: CHART-DxY0c3RnIv meta: - chartId: 9 + chartId: 3 height: 61 sliceName: Node counts sliceNameOverride: General node visit distribution @@ -58,7 +74,7 @@ position: children: [] id: CHART-cxqeW2rGoV meta: - chartId: 6 + chartId: 7 height: 50 sliceName: Node Visits sliceNameOverride: Node per dialog turn distribution @@ -71,11 +87,27 @@ position: - TAB-Gw0Ffh1lG - ROW-hNOZdWZpw type: CHART + CHART-eZttETxtot: + children: [] + id: CHART-eZttETxtot + meta: + chartId: 16 + height: 50 + sliceName: Responses + uuid: 7844eb6d-4fce-44cf-8994-fb61a221a2ab + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-lvxd9vvnS5 + type: CHART CHART-explore-10-1: children: [] id: CHART-explore-10-1 meta: - chartId: 8 + chartId: 10 height: 73 sliceName: Transition layout sliceNameOverride: Weighted transition graph @@ -92,7 +124,7 @@ position: children: [] id: CHART-explore-13-1 meta: - chartId: 12 + chartId: 11 height: 74 sliceName: Transition ratio [chord] sliceNameOverride: Weighted transition graph [chord plot] @@ -109,7 +141,7 @@ position: children: [] id: CHART-explore-14-1 meta: - chartId: 10 + chartId: 5 height: 105 sliceName: Node visits [sunburst] sliceNameOverride: Node visit distribution [sunburst] @@ -126,7 +158,7 @@ position: children: [] id: CHART-explore-15-1 meta: - chartId: 15 + chartId: 2 height: 50 sliceName: Current topic [time series bar chart] sliceNameOverride: Current topic slot [time series bar chart] @@ -143,7 +175,7 @@ position: children: [] id: CHART-explore-16-1 meta: - chartId: 16 + chartId: 4 height: 50 sliceName: Current topic slot [bar chart] uuid: a70c05d0-770b-4068-a55d-934283f5b1bb @@ -159,7 +191,7 @@ position: children: [] id: CHART-explore-17-1 meta: - chartId: 17 + chartId: 1 height: 50 sliceName: Rating slot [line chart] uuid: 128e1da2-1efd-433d-9b93-a07de175e2bc @@ -191,7 +223,7 @@ position: children: [] id: CHART-explore-22-1 meta: - chartId: 7 + chartId: 15 height: 61 sliceName: Terminal labels sliceNameOverride: Terminal labels monitor @@ -208,7 +240,7 @@ position: children: [] id: CHART-explore-9-1 meta: - chartId: 3 + chartId: 6 height: 105 sliceName: Node visits [ratio] sliceNameOverride: Node visit distribution [ratio] @@ -225,7 +257,7 @@ position: children: [] id: CHART-mYC2udeF3a meta: - chartId: 4 + chartId: 9 height: 50 sliceName: Service load [users] uuid: b5d43314-514c-464e-9fcc-f897e3ae0963 @@ -241,7 +273,7 @@ position: children: [] id: CHART-wci7CHiza6 meta: - chartId: 1 + chartId: 12 height: 66 sliceName: Transition counts sliceNameOverride: General transitions distribution @@ -508,6 +540,30 @@ position: - TAB-Gw0Ffh1lG - ROW-y6AC1wLv1j type: MARKDOWN + MARKDOWN-i9daMe46XY: + children: [] + id: MARKDOWN-i9daMe46XY + meta: + code: '## Requests and responses + + + The table charts below make it possible to explore the user requests and bot + responses produced in the scope of your conversational service. You can also + use the `Dialog turn` and `User ID` filters on the left to only consider the + requests produced by a particular user, etc. + + + Functions `get_last_request` and `get_last_response` need to be used to collect + the data.' + height: 26 + width: 12 + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + - ROW-DKYV2zUmwU + type: MARKDOWN MARKDOWN-pmSRDxroDW: children: [] id: MARKDOWN-pmSRDxroDW @@ -635,6 +691,18 @@ position: - TABS-Xoi5oUBxZI - TAB-JCU6rANFP type: ROW + ROW-DKYV2zUmwU: + children: + - MARKDOWN-i9daMe46XY + id: ROW-DKYV2zUmwU + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW ROW-EaYAQjv4W: children: - CHART-CuCYDOlGEu @@ -815,6 +883,30 @@ position: - TABS-Xoi5oUBxZI - TAB-6zE8noCIsx type: ROW + ROW-lvxd9vvnS5: + children: + - CHART-eZttETxtot + id: ROW-lvxd9vvnS5 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW + ROW-oXaTD35jB: + children: + - CHART-91whs_IaiF + id: ROW-oXaTD35jB + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - GRID_ID + - TABS-Xoi5oUBxZI + - TAB-Gw0Ffh1lG + type: ROW ROW-s_aeCbvt3: children: - CHART-explore-15-1 @@ -917,6 +1009,9 @@ position: - ROW-UiCWq3ix1 - ROW-tzfO7Zd-dD - ROW-hNOZdWZpw + - ROW-DKYV2zUmwU + - ROW-oXaTD35jB + - ROW-lvxd9vvnS5 id: TAB-Gw0Ffh1lG meta: defaultText: Tab title @@ -990,49 +1085,39 @@ metadata: '10': '#61a0a8' '11': '#d48265' '12': '#91c7ae' - '13': '#749f83' - '14': '#ca8622' - '15': '#bda29a' - '16': '#6e7074' + AVG(CAST(JSON_VALUE(data, '$.rating') AS...: '#c23531' + books: '#c23531' + films: '#2f4554' + games: '#61a0a8' + smalltalk: '#d48265' + animals, ask_about_breed: '#c23531' + animals, what_animal: '#61a0a8' + greeting_flow, node1: '#61a0a8' + news, what_news: '#749f83' + root, fallback: '#ca8622' + small_talk, ask_some_questions: '#61a0a8' animals: '#c23531' + greeting_flow: '#2f4554' news: '#2f4554' root: '#61a0a8' small_talk: '#d48265' - animals, ask_about_breed: '#c23531' animals, ask_about_color: '#2f4554' - animals, what_animal: '#61a0a8' - news, ask_about_science: '#d48265' - news, science_news: '#91c7ae' - news, what_news: '#749f83' - root, fallback: '#ca8622' - small_talk, ask_talk_about: '#bda29a' animals, ask_about_training: '#61a0a8' animals, have_pets: '#d48265' animals, like_animals: '#91c7ae' animals, tell_fact_about_breed: '#749f83' + greeting_flow, node2: '#6e7074' + greeting_flow, node3: '#546570' + greeting_flow, node4: '#c4ccd3' + news, ask_about_science: '#d48265' news, ask_about_sport: '#6e7074' + news, science_news: '#91c7ae' news, sport_news: '#c4ccd3' - small_talk, ask_some_questions: '#61a0a8' - AVG(CAST(JSON_VALUE(data, '$.rating') AS...: '#c23531' - books: '#c23531' - films: '#2f4554' - games: '#61a0a8' - smalltalk: '#d48265' - 'news: what_news': '#c23531' - 'small_talk: ask_talk_about': '#2f4554' - 'animals: tell_fact_about_breed': '#61a0a8' - 'news: sport_news': '#d48265' - 'animals: have_pets': '#91c7ae' - 'animals: ask_about_color': '#749f83' - 'small_talk: ask_some_questions': '#ca8622' - 'animals: what_animal': '#bda29a' - 'animals: ask_about_breed': '#6e7074' - 'root: fallback': '#546570' - 'news: science_news': '#c4ccd3' - 'animals: like_animals': '#c23531' - 'news: ask_about_science': '#2f4554' - 'animals: ask_about_training': '#61a0a8' - 'news: ask_about_sport': '#6e7074' + small_talk, ask_talk_about: '#bda29a' + node2: '#61a0a8' + node4: '#d48265' + node3: '#91c7ae' + node1: '#749f83' fallback: '#2f4554' ask_about_breed: '#d48265' what_animal: '#91c7ae' @@ -1048,6 +1133,25 @@ metadata: ask_about_sport: '#91c7ae' ask_some_questions: '#ca8622' ask_talk_about: '#bda29a' + 'animals: ask_about_breed': '#6e7074' + 'animals: ask_about_color': '#749f83' + 'animals: ask_about_training': '#61a0a8' + 'animals: have_pets': '#91c7ae' + 'animals: like_animals': '#c23531' + 'animals: tell_fact_about_breed': '#61a0a8' + 'animals: what_animal': '#bda29a' + 'greeting_flow: node1': '#bda29a' + 'greeting_flow: node2': '#6e7074' + 'greeting_flow: node3': '#546570' + 'greeting_flow: node4': '#c4ccd3' + 'news: ask_about_science': '#2f4554' + 'news: ask_about_sport': '#6e7074' + 'news: science_news': '#c4ccd3' + 'news: sport_news': '#d48265' + 'news: what_news': '#c23531' + 'root: fallback': '#546570' + 'small_talk: ask_some_questions': '#ca8622' + 'small_talk: ask_talk_about': '#2f4554' timed_refresh_immune_slices: [] expanded_slices: {} refresh_frequency: 1800 @@ -1087,7 +1191,7 @@ metadata: rootPath: - TAB-6zE8noCIsx excluded: - - 10 + - 5 type: NATIVE_FILTER description: '' chartsInScope: @@ -1114,7 +1218,7 @@ metadata: rootPath: - TAB-6zE8noCIsx excluded: - - 7 + - 15 type: NATIVE_FILTER description: '' chartsInScope: diff --git a/dff/config/superset_dashboard/metadata.yaml b/dff/config/superset_dashboard/metadata.yaml index c4d2fb8ed..421997817 100644 --- a/dff/config/superset_dashboard/metadata.yaml +++ b/dff/config/superset_dashboard/metadata.yaml @@ -1,3 +1,3 @@ version: 1.0.0 type: Dashboard -timestamp: '2023-09-14T12:24:44.253388+00:00' +timestamp: '2023-09-15T11:46:43.125179+00:00' diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 20058a990..5c271d314 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -69,7 +69,7 @@ {nodefield} as node_label, {table}.TraceId as trace_id, otel_traces.TraceId\nFROM {table}, otel_traces - WHERE {table}.TraceId = otel_traces.TraceId and otel_traces.SpanName = 'get_current_label' + WHERE {table}.TraceId = otel_traces.TraceId ORDER BY context_id, request_id ) SELECT context_id, request_id, @@ -81,7 +81,6 @@ flow_label, node_label FROM main -WHERE label != '' """ DFF_ACYCLIC_NODES_STATEMENT = """ WITH main AS ( diff --git a/dff/stats/default_extractors.py b/dff/stats/default_extractors.py index 8ffe4a049..6302b5594 100644 --- a/dff/stats/default_extractors.py +++ b/dff/stats/default_extractors.py @@ -57,23 +57,23 @@ async def get_timing_after(ctx: Context, _, info: ExtraHandlerRuntimeInfo): # n async def get_last_response(ctx: Context, _, info: ExtraHandlerRuntimeInfo): """ - Extract the last response in the current context. + Extract the text of the last response in the current context. This handler is best used together with the `ACTOR` component. This function is required to enable charts that aggregate requests and responses. """ - data = {"last_response": ctx.last_response} + data = {"last_response": ctx.last_response.text} return data async def get_last_request(ctx: Context, _, info: ExtraHandlerRuntimeInfo): """ - Extract the last request in the current context. + Extract the text of the last request in the current context. This handler is best used together with the `ACTOR` component. This function is required to enable charts that aggregate requests and responses. """ - data = {"last_request": ctx.last_request} + data = {"last_request": ctx.last_request.text} return data diff --git a/tests/stats/test_main.py b/tests/stats/test_main.py index 279565558..f6fcf0da0 100644 --- a/tests/stats/test_main.py +++ b/tests/stats/test_main.py @@ -63,6 +63,8 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): "Node visits [ratio]", "Node visits [sunburst]", "Rating slot [line chart]", + "Requests", + "Responses", "Service load [users]", "Table", "Terminal labels", @@ -83,8 +85,8 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): ] charts_result = session.get(charts_url, headers=headers) charts_json = charts_result.json() - assert charts_json["count"] == 15 - assert sorted(charts_json["ids"]) == list(range(1, 16)) + assert charts_json["count"] == 17 + assert sorted(charts_json["ids"]) == list(range(1, 18)) session.close() From 92318cdd21db4a8b135a655ef7b4cdd30d2261aa Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Mon, 18 Sep 2023 12:29:26 +0300 Subject: [PATCH 11/46] Update sections in superset_guide; update extractor functions tutor --- docs/source/user_guides/superset_guide.rst | 28 ++++++++++------------ tutorials/stats/1_extractor_functions.py | 14 +++++++---- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 5add23bde..fe81bab22 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -19,18 +19,20 @@ Collection procedure **Installation** .. code-block:: shell + :linenos: - pip install dff[stats] + # clone the original repository to access the docker-compose file + git clone https://github.com/deeppavlov/dialog_flow_framework.git + # install with the stats extra + cd dialog_flow_framework + pip install .[stats] **Launching services** .. code-block:: shell :linenos: - # clone the original repository to access the docker-compose file - git clone https://github.com/deeppavlov/dialog_flow_framework.git - # launch the required services - cd dialog_flow_framework + # When at the working directory, launch the services docker-compose up otelcol clickhouse dashboard **Collecting data** @@ -42,7 +44,7 @@ in order to obtain sample data points to visualize. .. code-block:: shell - export DISABLE_INTERACTIVE_MODE=1 && python tutorials/stats/1_extractor_functions.py + export DISABLE_INTERACTIVE_MODE=1 && python tutorials/stats/3_sample_data_provider.py Displaying the data ~~~~~~~~~~~~~~~~~~~ @@ -84,7 +86,7 @@ Using Superset | In order to view the imported dashboard, log into `Superset `_ using your username and password (which are both `superset` by default and can be configured via `.env_file`). | The dashboard will then be available in the **Dashboards** section of the Superset UI under the name of **DFF stats**. -| The dashboard has four sections, each one of them containing different kind of data. +| The dashboard is split into four sections based on the types of charts and on the chart topic. * The **Overview** section summarizes the information about user interaction with your script. And displays a weighted graph of transitions from one node to another. The data is also shown in the form of a table for better introspection capabilities. @@ -92,17 +94,11 @@ Using Superset Overview plots. -* The data displayed in the **General stats** section reports, how frequent each of the nodes in your script was visited by users. The information is aggregated in several forms for better interpretability. +* The data displayed in the **Node stats** section reports, how frequent each of the nodes in your script was visited by users. The information is aggregated in several forms for better interpretability. .. figure:: ../_static/images/general_stats.png - General stats plots. - -* The **Additional stats** section includes charts for node visit counts aggregated over various specific variables. - -.. figure:: ../_static/images/additional_stats.png - - Additional stats plots. + Node stats plots. * General service load data aggregated over time can be found in the **Service stats** section. @@ -110,6 +106,8 @@ Using Superset Service stats plots. +* The `Annotations` section contains example charts that show how annotations from supplemental pipeline services can be viewed and analyzed. + On some occasions, Superset can show warnings about the database connection being faulty. In that case, you can navigate to the `Database Connections` section through the `Settings` menu and edit the `dff_database` instance updating the credentials. diff --git a/tutorials/stats/1_extractor_functions.py b/tutorials/stats/1_extractor_functions.py index 20f371ba6..d91f049e9 100644 --- a/tutorials/stats/1_extractor_functions.py +++ b/tutorials/stats/1_extractor_functions.py @@ -9,10 +9,13 @@ provides several default extractors, but users are free to define their own extractor functions. -It is required that the extractors have the following uniform signature: +It is a preferred practice to define extractors as asynchronous functions. +Extractors need to have the following uniform signature: the expected arguments are always `Context`, `Pipeline`, and `ExtraHandlerRuntimeInfo`, -while the expected return value is an arbitrary `dict` or a `None`. It is a preferred practice -to define extractors as asynchronous functions. +while the expected return value is an arbitrary `dict` or a `None`. +The returned value gets persisted to Clickhouse as JSON +which is why it can contain arbitrarily nested dictionaries, +but it cannot contain any complex objects that cannot be trivially serialized. The output of these functions will be captured by an OpenTelemetry instrumentor and directed to the Opentelemetry collector server which in its turn batches and persists data @@ -49,8 +52,9 @@ an appropriate Opentelemetry exporter instance and bind it to provider classes. * Nextly, the `OtelInstrumentor` class should be constructed to log the output -of extractor functions. Custom extractors can be decorated with the `OtelInstrumentor` instance. -Default extractors are instrumented by calling the `instrument` method. +of extractor functions. Custom extractors need to be decorated +with the `OtelInstrumentor` instance. Default extractors are instrumented +by calling the `instrument` method. * The entirety of the process is illustrated in the example below. From e45c2982835638f4b1ce95f5e647af1c3dd9912d Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Mon, 18 Sep 2023 13:45:27 +0300 Subject: [PATCH 12/46] doc build fix: Change functions to func names in __all__ --- dff/stats/default_extractors.py | 7 ++++++- dff/stats/instrumentor.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dff/stats/default_extractors.py b/dff/stats/default_extractors.py index 6302b5594..d39d503c6 100644 --- a/dff/stats/default_extractors.py +++ b/dff/stats/default_extractors.py @@ -77,4 +77,9 @@ async def get_last_request(ctx: Context, _, info: ExtraHandlerRuntimeInfo): return data -__all__ = [get_current_label, get_timing_before, get_timing_after, get_last_request, get_last_response] +__all__ = ["get_current_label", "get_timing_before", "get_timing_after", "get_last_request", "get_last_response"] +""" +List of exported functions. + +:meta hide-avlue: +""" diff --git a/dff/stats/instrumentor.py b/dff/stats/instrumentor.py index d5f341624..41f7c2ca5 100644 --- a/dff/stats/instrumentor.py +++ b/dff/stats/instrumentor.py @@ -126,11 +126,11 @@ def _instrument(self, logger_provider=None, tracer_provider=None, meter_provider self._configure_providers( logger_provider=logger_provider, tracer_provider=tracer_provider, meter_provider=meter_provider ) - for func_name in [func.__name__ for func in default_extractors.__all__]: + for func_name in default_extractors.__all__: wrap_function_wrapper(default_extractors, func_name, self.__call__.__wrapped__) def _uninstrument(self, **kwargs): - for func_name in [func.__name__ for func in default_extractors.__all__]: + for func_name in default_extractors.__all__: unwrap(default_extractors, func_name) def _configure_providers(self, logger_provider, tracer_provider, meter_provider): From ac0023016f3cc7c8ae7e87e8cca5286debe316ce Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 20 Sep 2023 10:31:57 +0300 Subject: [PATCH 13/46] Apply suggestions by RLKRO from code review Co-authored-by: Roman Zlobin --- dff/utils/testing/toy_script.py | 2 +- tutorials/stats/3_sample_data_provider.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dff/utils/testing/toy_script.py b/dff/utils/testing/toy_script.py index 811ef2fa4..fde420013 100644 --- a/dff/utils/testing/toy_script.py +++ b/dff/utils/testing/toy_script.py @@ -198,7 +198,7 @@ }, } """ -Request options for automated client requests. +Request options for automated client requests for :py:data:`~.MULTIFLOW_SCRIPT`. :meta hide-value: """ diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py index 03ebe1345..725d3c4fe 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/tutorials/stats/3_sample_data_provider.py @@ -95,8 +95,7 @@ async def worker(queue: asyncio.Queue): answers = list(MULTIFLOW_REQUEST_OPTIONS.get(flow, {}).get(node, [])) in_text = random.choice(answers) if answers else "go to fallback" in_message = Message(text=in_text) - rand_interval = float(random.randint(0, 1)) + random.random() - await asyncio.sleep(rand_interval) + await asyncio.sleep(random.random() * 2) ctx = await pipeline._run_pipeline(in_message, ctx.id) rand_interval = float(random.randint(0, 1)) + random.random() await asyncio.sleep(rand_interval) From 1d5a92a0a25be204f9543d51e499b7e881cbfd8f Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 20 Sep 2023 13:19:19 +0300 Subject: [PATCH 14/46] intermediary update; update data provider tutor; update charts; --- .../Current_topic_slot_bar_chart_4.yaml | 24 ++++++++-------- .../charts/Requests_17.yaml | 6 +++- .../charts/Responses_16.yaml | 6 +++- .../DFF_statistics_dashboard_1.yaml | 2 +- dff/utils/testing/toy_script.py | 2 +- docs/source/user_guides/superset_guide.rst | 6 ++-- tutorials/stats/3_sample_data_provider.py | 28 +++++++++++-------- 7 files changed, 43 insertions(+), 31 deletions(-) diff --git a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml index 028bbe494..f8fbc5b76 100644 --- a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml +++ b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml @@ -6,7 +6,7 @@ viz_type: dist_bar params: datasource: 2__table viz_type: dist_bar - slice_id: 16 + slice_id: 6 granularity_sqla: start_time time_range: No filter metrics: @@ -34,11 +34,11 @@ params: sqlExpression: JSON_VALUE(data, '$.current_topic') <> '' subject: null groupby: - - expressionType: SQL - label: My column - sqlExpression: JSON_VALUE(data, '$.current_topic') - columns: - request_id + columns: + - label: My column + sqlExpression: JSON_VALUE(data, '$.current_topic') + expressionType: SQL row_limit: 10000 order_desc: true color_scheme: echarts4Colors @@ -47,11 +47,11 @@ params: bar_stacked: true order_bars: false y_axis_format: SMART_NUMBER - y_axis_label: Counts + y_axis_label: Topic counts y_axis_bounds: - null - null - x_axis_label: Topic slot values + x_axis_label: Dialog turn bottom_margin: auto x_ticks_layout: auto extra_form_data: {} @@ -59,12 +59,12 @@ params: - 1 query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"having":"","where":"(JSON_VALUE(data, - ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":[{"expressionType":"SQL","label":"My - column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')"},"request_id"],"metrics":["count"],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":16,"granularity_sqla":"start_time","time_range":"No + ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":["request_id",{"label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","expressionType":"SQL"}],"metrics":["count"],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":6,"granularity_sqla":"start_time","time_range":"No filter","metrics":["count"],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_sz14lhn7d1d_c0zqn5dpgk","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_945dhn41x2m_sci7gkxy7o","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, - ''$.current_topic'') <> ''''","subject":null}],"groupby":[{"expressionType":"SQL","label":"My - column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')"}],"columns":["request_id"],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":false,"y_axis_format":"SMART_NUMBER","y_axis_label":"Counts","y_axis_bounds":[null,null],"x_axis_label":"Topic - slot values","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + ''$.current_topic'') <> ''''","subject":null}],"groupby":["request_id"],"columns":[{"label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","expressionType":"SQL"}],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":false,"y_axis_format":"SMART_NUMBER","y_axis_label":"Topic + counts","y_axis_bounds":[null,null],"x_axis_label":"Dialog turn","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: a70c05d0-770b-4068-a55d-934283f5b1bb version: 1.0.0 diff --git a/dff/config/superset_dashboard/charts/Requests_17.yaml b/dff/config/superset_dashboard/charts/Requests_17.yaml index f6cadd058..09dc50879 100644 --- a/dff/config/superset_dashboard/charts/Requests_17.yaml +++ b/dff/config/superset_dashboard/charts/Requests_17.yaml @@ -38,13 +38,17 @@ params: table_timestamp_format: smart_date show_cell_bars: true color_pn: true + column_config: + data: + columnWidth: 150 + truncateLongCells: true extra_form_data: {} dashboards: [] query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_request"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, ''$.last_request'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 45ef67db-d33d-49f5-8d46-1f0fa518eaac version: 1.0.0 diff --git a/dff/config/superset_dashboard/charts/Responses_16.yaml b/dff/config/superset_dashboard/charts/Responses_16.yaml index a4f8d5df2..c136e4377 100644 --- a/dff/config/superset_dashboard/charts/Responses_16.yaml +++ b/dff/config/superset_dashboard/charts/Responses_16.yaml @@ -38,13 +38,17 @@ params: table_timestamp_format: smart_date show_cell_bars: true color_pn: true + column_config: + data: + columnWidth: 150 + truncateLongCells: true extra_form_data: {} dashboards: [] query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_response"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, ''$.last_response'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 7844eb6d-4fce-44cf-8994-fb61a221a2ab version: 1.0.0 diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 2556d6e9f..41a4c6bf0 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -326,7 +326,7 @@ position: code: '## Flow visit ratio monitor - Thus chart aggregates the ratio of visits for each flow over the whole period + This chart aggregates the ratio of visits for each flow over the whole period of service uptime. The aggregation period can be set to shorter time spans using the filters on the left.' height: 17 diff --git a/dff/utils/testing/toy_script.py b/dff/utils/testing/toy_script.py index fde420013..b887a01f7 100644 --- a/dff/utils/testing/toy_script.py +++ b/dff/utils/testing/toy_script.py @@ -179,7 +179,7 @@ "have_pets": ["yes"], "like_animals": ["yes"], "what_animal": ["bird", "dog"], - "ask_about_breed": ["pereat", "bulldog", "i do not known"], + "ask_about_breed": ["pereat", "bulldog", "I don't know"], }, "news": { "what_news": ["science", "sport"], diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index fe81bab22..156df3c47 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -44,7 +44,7 @@ in order to obtain sample data points to visualize. .. code-block:: shell - export DISABLE_INTERACTIVE_MODE=1 && python tutorials/stats/3_sample_data_provider.py + python tutorials/stats/3_sample_data_provider.py Displaying the data ~~~~~~~~~~~~~~~~~~~ @@ -106,11 +106,11 @@ Using Superset Service stats plots. -* The `Annotations` section contains example charts that show how annotations from supplemental pipeline services can be viewed and analyzed. +* The **Annotations** section contains example charts that show how annotations from supplemental pipeline services can be viewed and analyzed. On some occasions, Superset can show warnings about the database connection being faulty. In that case, you can navigate to the `Database Connections` section through the `Settings` menu and edit the `dff_database` instance updating the credentials. .. figure:: ../_static/images/databases.png - Locate the database settings in the right corner of the screen. \ No newline at end of file + Locate the database settings in the right corner of the screen. diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py index 725d3c4fe..22b6ad9e2 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/tutorials/stats/3_sample_data_provider.py @@ -20,7 +20,6 @@ default_extractors, OtelInstrumentor, ) -from dff.utils.testing import is_interactive_mode from dff.utils.testing.toy_script import MULTIFLOW_SCRIPT, MULTIFLOW_REQUEST_OPTIONS # %% @@ -43,12 +42,12 @@ async def get_slots(ctx: Context, _, info: ExtraHandlerRuntimeInfo): def confidence_processor(ctx: Context): - ctx.framework_states["response_confidence"] = random.random() + ctx.misc["response_confidence"] = random.random() @dff_instrumentor async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): - data = {"response_confidence": ctx.framework_states["response_confidence"]} + data = {"response_confidence": ctx.misc["response_confidence"]} return data @@ -61,17 +60,19 @@ async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): "components": [ Service(slot_processor_1, after_handler=[get_slots]), Service(slot_processor_2, after_handler=[get_slots]), - Service(confidence_processor, after_handler=[get_confidence]), Service( handler=ACTOR, - before_handler=[default_extractors.get_timing_before], + before_handler=[ + default_extractors.get_timing_before, + default_extractors.get_current_label, + ], after_handler=[ default_extractors.get_timing_after, - default_extractors.get_current_label, default_extractors.get_last_request, default_extractors.get_last_response, ], ), + Service(confidence_processor, after_handler=[get_confidence]), ], } ) @@ -81,6 +82,11 @@ async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): async def worker(queue: asyncio.Queue): """ Worker function for dispatching one client message. + The client message is chosen randomly from a predetermined set of options. + It simulates pauses in between messages by calling the sleep function. + + The function also starts a new dialog as a new user, if the current dialog + ended in the fallback_node. :param queue: Queue for sharing context variables. """ @@ -95,10 +101,9 @@ async def worker(queue: asyncio.Queue): answers = list(MULTIFLOW_REQUEST_OPTIONS.get(flow, {}).get(node, [])) in_text = random.choice(answers) if answers else "go to fallback" in_message = Message(text=in_text) - await asyncio.sleep(random.random() * 2) + await asyncio.sleep(random.random() * 3) ctx = await pipeline._run_pipeline(in_message, ctx.id) - rand_interval = float(random.randint(0, 1)) + random.random() - await asyncio.sleep(rand_interval) + await asyncio.sleep(random.random() * 3) await queue.put(ctx) @@ -106,7 +111,7 @@ async def worker(queue: asyncio.Queue): # main loop async def main(n_iterations: int = 100, n_workers: int = 4): """ - Main loop that runs one or more worker coroutines in parallel. + The main loop that runs one or more worker coroutines in parallel. :param n_iterations: Total number of coroutine runs. :param n_workers: Number of parallelized coroutine runs. @@ -120,5 +125,4 @@ async def main(n_iterations: int = 100, n_workers: int = 4): if __name__ == "__main__": - if is_interactive_mode(): - asyncio.run(main()) + asyncio.run(main()) From ce2f1d72133c4c84336f272ff7e9d430d8abc30f Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 20 Sep 2023 13:30:33 +0300 Subject: [PATCH 15/46] Apply suggestions from code review by RLKRO Co-authored-by: Roman Zlobin --- .../dashboards/DFF_statistics_dashboard_1.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 41a4c6bf0..2298f024f 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -327,8 +327,7 @@ position: This chart aggregates the ratio of visits for each flow over the whole period - of service uptime. The aggregation period can be set to shorter time spans - using the filters on the left.' + of service uptime. The aggregation period can be set using the filters on the left.' height: 17 width: 12 parents: @@ -351,9 +350,7 @@ position: This can reveal characteristic features of user behavior given the current - dialog structure - - that call for changes. + dialog structure.
@@ -550,7 +547,7 @@ position: The table charts below make it possible to explore the user requests and bot responses produced in the scope of your conversational service. You can also use the `Dialog turn` and `User ID` filters on the left to only consider the - requests produced by a particular user, etc. + requests produced by a particular user or requests sent on a specific dialog turn. Functions `get_last_request` and `get_last_response` need to be used to collect From ee8670328409434b097314980700da4f5ea75e0f Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 20 Sep 2023 13:53:05 +0300 Subject: [PATCH 16/46] Upload annotations.png via GUI --- docs/source/_static/images/annotations.png | Bin 0 -> 64834 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/source/_static/images/annotations.png diff --git a/docs/source/_static/images/annotations.png b/docs/source/_static/images/annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..b1e524890a8345a7f15acf071f5634524c7b61f4 GIT binary patch literal 64834 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 Date: Wed, 20 Sep 2023 18:14:20 +0300 Subject: [PATCH 17/46] Update requests & responses charts; update superset_guide --- .../charts/Requests_17.yaml | 4 +- .../charts/Responses_16.yaml | 4 +- .../DFF_statistics_dashboard_1.yaml | 121 ++++++++---------- docs/source/user_guides/superset_guide.rst | 4 + 4 files changed, 58 insertions(+), 75 deletions(-) diff --git a/dff/config/superset_dashboard/charts/Requests_17.yaml b/dff/config/superset_dashboard/charts/Requests_17.yaml index 09dc50879..a9289f7e2 100644 --- a/dff/config/superset_dashboard/charts/Requests_17.yaml +++ b/dff/config/superset_dashboard/charts/Requests_17.yaml @@ -35,7 +35,7 @@ params: row_limit: 1000 server_page_length: 10 order_desc: true - table_timestamp_format: smart_date + table_timestamp_format: '%d-%m-%Y %H:%M:%S' show_cell_bars: true color_pn: true column_config: @@ -48,7 +48,7 @@ query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{ filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_request"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, ''$.last_request'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 45ef67db-d33d-49f5-8d46-1f0fa518eaac version: 1.0.0 diff --git a/dff/config/superset_dashboard/charts/Responses_16.yaml b/dff/config/superset_dashboard/charts/Responses_16.yaml index c136e4377..c6ac78b70 100644 --- a/dff/config/superset_dashboard/charts/Responses_16.yaml +++ b/dff/config/superset_dashboard/charts/Responses_16.yaml @@ -35,7 +35,7 @@ params: row_limit: 1000 server_page_length: 10 order_desc: true - table_timestamp_format: smart_date + table_timestamp_format: '%d-%m-%Y %H:%M:%S' show_cell_bars: true color_pn: true column_config: @@ -48,7 +48,7 @@ query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{ filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_response"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, ''$.last_response'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 7844eb6d-4fce-44cf-8994-fb61a221a2ab version: 1.0.0 diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 2298f024f..55731ed8a 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -524,10 +524,7 @@ position: Based on this information, you can determine which transitions inside the dialog graph function - as intended. If some edge has never been traversed, it is safe to draw the - conclusion that transition - - conditions need to be adjusted.' + as intended.' height: 24 width: 12 parents: @@ -1082,73 +1079,6 @@ metadata: '10': '#61a0a8' '11': '#d48265' '12': '#91c7ae' - AVG(CAST(JSON_VALUE(data, '$.rating') AS...: '#c23531' - books: '#c23531' - films: '#2f4554' - games: '#61a0a8' - smalltalk: '#d48265' - animals, ask_about_breed: '#c23531' - animals, what_animal: '#61a0a8' - greeting_flow, node1: '#61a0a8' - news, what_news: '#749f83' - root, fallback: '#ca8622' - small_talk, ask_some_questions: '#61a0a8' - animals: '#c23531' - greeting_flow: '#2f4554' - news: '#2f4554' - root: '#61a0a8' - small_talk: '#d48265' - animals, ask_about_color: '#2f4554' - animals, ask_about_training: '#61a0a8' - animals, have_pets: '#d48265' - animals, like_animals: '#91c7ae' - animals, tell_fact_about_breed: '#749f83' - greeting_flow, node2: '#6e7074' - greeting_flow, node3: '#546570' - greeting_flow, node4: '#c4ccd3' - news, ask_about_science: '#d48265' - news, ask_about_sport: '#6e7074' - news, science_news: '#91c7ae' - news, sport_news: '#c4ccd3' - small_talk, ask_talk_about: '#bda29a' - node2: '#61a0a8' - node4: '#d48265' - node3: '#91c7ae' - node1: '#749f83' - fallback: '#2f4554' - ask_about_breed: '#d48265' - what_animal: '#91c7ae' - ask_about_color: '#749f83' - tell_fact_about_breed: '#ca8622' - like_animals: '#bda29a' - ask_about_training: '#6e7074' - have_pets: '#546570' - sport_news: '#c23531' - what_news: '#2f4554' - science_news: '#61a0a8' - ask_about_science: '#d48265' - ask_about_sport: '#91c7ae' - ask_some_questions: '#ca8622' - ask_talk_about: '#bda29a' - 'animals: ask_about_breed': '#6e7074' - 'animals: ask_about_color': '#749f83' - 'animals: ask_about_training': '#61a0a8' - 'animals: have_pets': '#91c7ae' - 'animals: like_animals': '#c23531' - 'animals: tell_fact_about_breed': '#61a0a8' - 'animals: what_animal': '#bda29a' - 'greeting_flow: node1': '#bda29a' - 'greeting_flow: node2': '#6e7074' - 'greeting_flow: node3': '#546570' - 'greeting_flow: node4': '#c4ccd3' - 'news: ask_about_science': '#2f4554' - 'news: ask_about_sport': '#6e7074' - 'news: science_news': '#c4ccd3' - 'news: sport_news': '#d48265' - 'news: what_news': '#c23531' - 'root: fallback': '#546570' - 'small_talk: ask_some_questions': '#ca8622' - 'small_talk: ask_talk_about': '#2f4554' timed_refresh_immune_slices: [] expanded_slices: {} refresh_frequency: 1800 @@ -1308,5 +1238,54 @@ metadata: - TAB-Gw0Ffh1lG - TAB-JCU6rANFP - TAB-q4CdGUDlq + - id: NATIVE_FILTER-BU7iNmYAX + adhoc_filters: + - expressionType: SQL + sqlExpression: label <> '' + clause: WHERE + subject: null + operator: null + comparator: null + isExtra: false + isNew: false + datasourceWarning: false + filterOptionName: filter_68jo660l3a3_xn0lv9ghc2i + time_range: No filter + controlValues: + enableEmptyFilter: false + defaultToFirstItem: false + multiSelect: true + searchAllOptions: false + inverseSelection: false + name: Node + filterType: filter_select + targets: + - column: + name: label + datasetUuid: fda98ab8-f550-45f1-9ded-0113f3e67260 + defaultDataMask: + extraFormData: {} + filterState: {} + ownState: {} + cascadeParentIds: [] + scope: + rootPath: + - TAB-Gw0Ffh1lG + - TAB-q4CdGUDlq + excluded: [] + type: NATIVE_FILTER + description: '' + chartsInScope: + - 1 + - 3 + - 6 + - 9 + - 10 + - 15 + - 16 + - 17 + tabsInScope: + - TAB-Gw0Ffh1lG + - TAB-q4CdGUDlq stagger_refresh: true version: 1.0.0 diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 156df3c47..770232c64 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -108,6 +108,10 @@ Using Superset * The **Annotations** section contains example charts that show how annotations from supplemental pipeline services can be viewed and analyzed. +.. figure:: ../_static/images/annotations.png + + Plots for pipeline-produced dialog annotations. + On some occasions, Superset can show warnings about the database connection being faulty. In that case, you can navigate to the `Database Connections` section through the `Settings` menu and edit the `dff_database` instance updating the credentials. From fd05a11d04980328a9a52ac0495307710086a059 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 21 Sep 2023 15:34:42 +0300 Subject: [PATCH 18/46] expand the Superset guide with chart creation instructions;Add links to Superset documentation --- .../DFF_statistics_dashboard_1.yaml | 10 ++- docs/source/user_guides/superset_guide.rst | 63 +++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 55731ed8a..ce0e7819c 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -378,13 +378,17 @@ position: To make them available in the dashboard, you need to define a custom extractor - function for them (see `Extractor functions` tutorial for more information). + function for them (see the [Extractor functions](https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.stats.1_extractor_functions.html) ). The output of that function will then be persisted to the `data` column of the logs table, while the name of the function will be available in the `data key` column. That makes it easy to filter the relevant log entries and use them to build a Superset chart. + If you need custom charts, consult the official Superset documentation for + instructions on how to create those: [link](https://superset.apache.org/docs/creating-charts-dashboards/exploring-data/#pivot-table). + + It''s important to keep in mind that `data` is a JSON column, which is why you need to specify your own `custom sql` expression to get the relevant value. @@ -407,8 +411,8 @@ position: **Note that the charts below will only display meaningful figures if the respective - annotation values have been collected. To get those, run the `sample data - provider` tutorial.**' + annotation values have been collected. To get those, run the [Sample data + provider script](#).**' height: 63 width: 12 parents: diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 770232c64..43827c09a 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -118,3 +118,66 @@ In that case, you can navigate to the `Database Connections` section through the .. figure:: ../_static/images/databases.png Locate the database settings in the right corner of the screen. + +Custom dashboard elements +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The most notable advantage of using Superset as a visualization tool is that it provides +an easy and intuitive way to create your own charts and to customize the dashboard. + +**Datasets** + +If you aim to create your own chart, Superset will prompt you to select a dataset to draw data from. +The current configuration provides two datasets `dff-node-stats` and `dff-final-nodes`. In most cases, +you will need to use `dff-node-stats`, since `dff-final-nodes` contains the same information, but only +aggregates terminal nodes. + +`dff-nodes-stats` uses the following variables to store the data: + +* The `context_id` field can be used to distinguish dialog contexts from each other and serves +as a user identifier. +* `request_id` is the number of the dialog turn at which the data record was emitted. The data points +can be aggregated over this field, showing the distribution of a variable over the dialog history. +* The `data_key` field contains the name of the extractor function that emitted the given record. +Since in most cases you will only need the output of one extractor, you can filter out all the other +records using filters. +* Finally, the `data` field is a set of JSON-encoded key-value pairs. The keys and values differ depending +on the extractor function that emitted the data (you can essentially save arbitrary data under arbitrary keys), +which makes filtering the data rows by their `data_key` all the more important. The JSON format implies +that individual values need to be extracted using the Superset SQL functions (see below). + +.. code-block:: + + JSON_VALUE(data, '$.key') + JSON_VALUE(data, '$.outer_key.nested_key') + +**Chart creation** + +.. note:: + + Chart creation is described in detail in the official Superset documentation. + We suggest that you consult it in addition to this section: + `link `_. + +Creating your own chart is as easy as navigating to the `Charts` section of the Superset app +and pressing the `Create` button. + +Initially, you will be prompted for the dataset that you want to use as well as for the chart type. +The Superset GUI provides comprehensive previews of each chart type making it very easy +to find the exact chart that you need. + +At the next step you will be redirected to the chart creation interface. +Depending on the kind of chat that you have chosen previously, there will be menus available +to choose a column for the x-axis and, optionally, a column for the y-axis. As mentioned above, +a separate menu for data filters will also be available. If you need to draw data +from the `data` column, you will need to find the `custom_sql` option when adding the column +and put in the extraction expression, as shown in the examples above. + +**Persisting the chart configuration** + +If you define your own charts, it's important to save their configuration to the file system of your +host machine, so that no information is lost when the Superset container or the Docker process is restarted. + +The most convenient way to do that is to export the dashboard configuration as a whole. Navigate to the +`Dashboards` section of the Superset application, locate your dashboard (named `DFF statistics` per default). +Then press the `export` button on the right and save the zip file to any convenient location. \ No newline at end of file From 675e71b0935327cec96ae22fdba8469e61f3a5cc Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 21 Sep 2023 17:37:30 +0300 Subject: [PATCH 19/46] update graph plot; update dataset to get flow lag; update data provider --- .../charts/Transition_layout_10.yaml | 4 ++-- .../datasets/dff_database/dff_node_stats.yaml | 14 +++++++++++++- dff/stats/cli.py | 6 ++++-- docs/source/user_guides/superset_guide.rst | 16 +++++----------- tutorials/stats/3_sample_data_provider.py | 7 +++++-- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/dff/config/superset_dashboard/charts/Transition_layout_10.yaml b/dff/config/superset_dashboard/charts/Transition_layout_10.yaml index fd22359b5..8b674fd59 100644 --- a/dff/config/superset_dashboard/charts/Transition_layout_10.yaml +++ b/dff/config/superset_dashboard/charts/Transition_layout_10.yaml @@ -36,7 +36,7 @@ params: label: COUNT(context_id) optionName: metric_qxsyaujh63_4b75kyx6b5g sqlExpression: null - source_category: flow_label + source_category: prev_flow target_category: flow_label adhoc_filters: - expressionType: SIMPLE @@ -92,7 +92,7 @@ params: query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_current_label"}],"extras":{"having":"","where":"(label <> '''') AND (prev_label <> '''')"},"applied_time_extras":{},"columns":["prev_label","label","flow_label"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_qxsyaujh63_4b75kyx6b5g","sqlExpression":null}],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"graph_chart","slice_id":8,"granularity_sqla":"start_time","time_range":"No - filter","source":"prev_label","target":"label","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_qxsyaujh63_4b75kyx6b5g","sqlExpression":null},"source_category":"flow_label","target_category":"flow_label","adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_avle3r80zu4_c4684cbrjfg"},{"expressionType":"SQL","sqlExpression":"label + filter","source":"prev_label","target":"label","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"context_id","description":null,"expression":null,"filterable":true,"groupby":true,"id":1,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"STRING","type_generic":1,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(context_id)","optionName":"metric_qxsyaujh63_4b75kyx6b5g","sqlExpression":null},"source_category":"prev_flow","target_category":"flow_label","adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_current_label","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_avle3r80zu4_c4684cbrjfg"},{"expressionType":"SQL","sqlExpression":"label <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_0jip6y1w3awu_eysm19dnp2"},{"expressionType":"SQL","sqlExpression":"prev_label <> ''''","clause":"WHERE","subject":null,"operator":null,"comparator":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_29oq8kbalhr_6wudwxysro"}],"row_limit":10000,"color_scheme":"echarts4Colors","show_legend":true,"legendType":"scroll","legendOrientation":"top","layout":"force","edgeSymbol":"none,arrow","draggable":false,"roam":"scale","selectedMode":"single","baseNodeSize":20,"baseEdgeWidth":3,"edgeLength":400,"gravity":0.3,"repulsion":1000,"friction":0.2,"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index b696524ca..60a97ea13 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -14,7 +14,7 @@ sql: "\nWITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id' FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId\n\ \ ORDER BY context_id, request_id\n) SELECT context_id,\n request_id,\n \ \ start_time,\n data_key,\n data,\n label,\n neighbor(label, -1) as\ - \ prev_label,\n flow_label,\n node_label\nFROM main\n" + \ prev_label,\n, neighbor(flow_label, -1) as prev_flow, flow_label,\n node_label\nFROM main\n" params: null template_params: null filter_select_enabled: false @@ -79,6 +79,18 @@ columns: description: null python_date_format: null extra: {} +- column_name: prev_flow + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} - column_name: flow_label verbose_name: null is_dttm: false diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 5c271d314..d47f38176 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -77,7 +77,8 @@ data_key, data, label, - {lag} as prev_label, + {label_lag} as prev_label, + {flow_lag} as prev_flow, flow_label, node_label FROM main @@ -193,7 +194,8 @@ def make_zip_config(parsed_args: argparse.Namespace) -> Path: if OmegaConf.select(cli_conf, "db.driver") == "clickhousedb+connect": params = dict( table="${db.table}", - lag="neighbor(label, -1)", + label_lag="neighbor(label, -1)", + flow_lag="neighbor(flow_label, -1)", texttype="String", lblfield="JSON_VALUE(${db.table}.Body, '$.label')", flowfield="JSON_VALUE(${db.table}.Body, '$.flow')", diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 43827c09a..a91928d5a 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -134,17 +134,11 @@ aggregates terminal nodes. `dff-nodes-stats` uses the following variables to store the data: -* The `context_id` field can be used to distinguish dialog contexts from each other and serves -as a user identifier. -* `request_id` is the number of the dialog turn at which the data record was emitted. The data points -can be aggregated over this field, showing the distribution of a variable over the dialog history. -* The `data_key` field contains the name of the extractor function that emitted the given record. -Since in most cases you will only need the output of one extractor, you can filter out all the other -records using filters. -* Finally, the `data` field is a set of JSON-encoded key-value pairs. The keys and values differ depending -on the extractor function that emitted the data (you can essentially save arbitrary data under arbitrary keys), -which makes filtering the data rows by their `data_key` all the more important. The JSON format implies -that individual values need to be extracted using the Superset SQL functions (see below). +* The `context_id` field can be used to distinguish dialog contexts from each other and serves as a user identifier. +* `request_id` is the number of the dialog turn at which the data record was emitted. The data points can be aggregated over this field, showing the distribution of a variable over the dialog history. +* The `data_key` field contains the name of the extractor function that emitted the given record. Since in most cases you will only need the output of one extractor, you can filter out all the other records using filters. +* Finally, the `data` field is a set of JSON-encoded key-value pairs. The keys and values differ depending on the extractor function that emitted the data (you can essentially save arbitrary data under arbitrary keys), which makes filtering the data rows by their `data_key` all the more important. The JSON format implies that individual values need to be extracted using the Superset SQL functions (see below). + .. code-block:: diff --git a/tutorials/stats/3_sample_data_provider.py b/tutorials/stats/3_sample_data_provider.py index 22b6ad9e2..5c4e1262c 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/tutorials/stats/3_sample_data_provider.py @@ -29,11 +29,14 @@ def slot_processor_1(ctx: Context): - ctx.misc["slots"] = {"rating": random.randint(1, 10)} + ctx.misc["slots"] = {**ctx.misc.get("slots", {}), "rating": random.randint(1, 10)} def slot_processor_2(ctx: Context): - ctx.misc["slots"] = {"current_topic": random.choice(["films", "games", "books", "smalltalk"])} + ctx.misc["slots"] = { + **ctx.misc.get("slots", {}), + "current_topic": random.choice(["films", "games", "books", "smalltalk"]), + } @dff_instrumentor From 6af9a9f69a4b2de20e904cdfa78bd775b19f2351 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 22 Sep 2023 12:26:15 +0300 Subject: [PATCH 20/46] update guide; move sample data collector to /utils --- docs/source/user_guides/superset_guide.rst | 18 +++++++++--------- .../stats/sample_data_provider.py | 5 +---- 2 files changed, 10 insertions(+), 13 deletions(-) rename tutorials/stats/3_sample_data_provider.py => utils/stats/sample_data_provider.py (98%) diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index a91928d5a..42b3caaef 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -38,13 +38,13 @@ Collection procedure **Collecting data** Collecting data is done by means of instrumenting your conversational service before you run it. -DFF tutorials showcase all the necessary steps, needed to achieve that. We will run -`one of those files <../tutorials/tutorials.stats.1_extractor_functions.py>`_ -in order to obtain sample data points to visualize. +DFF tutorials (`1`_, `2`_) +showcase all the steps needed to achieve that. We will run +a special script in order to obtain richly-annotated sample data points to visualize. .. code-block:: shell - python tutorials/stats/3_sample_data_provider.py + python utils/stats/sample_data_provider.py Displaying the data ~~~~~~~~~~~~~~~~~~~ @@ -119,7 +119,7 @@ In that case, you can navigate to the `Database Connections` section through the Locate the database settings in the right corner of the screen. -Custom dashboard elements +Customizing the dashboard ~~~~~~~~~~~~~~~~~~~~~~~~~ The most notable advantage of using Superset as a visualization tool is that it provides @@ -158,12 +158,12 @@ and pressing the `Create` button. Initially, you will be prompted for the dataset that you want to use as well as for the chart type. The Superset GUI provides comprehensive previews of each chart type making it very easy -to find the exact chart that you need. +to find the exact kind that you need. -At the next step you will be redirected to the chart creation interface. -Depending on the kind of chat that you have chosen previously, there will be menus available +At the next step, you will be redirected to the chart creation interface. +Depending on the kind of chat that you have chosen previously, menus will be available to choose a column for the x-axis and, optionally, a column for the y-axis. As mentioned above, -a separate menu for data filters will also be available. If you need to draw data +a separate menu for data filters will also be available. If you need to use the data from the `data` column, you will need to find the `custom_sql` option when adding the column and put in the extraction expression, as shown in the examples above. diff --git a/tutorials/stats/3_sample_data_provider.py b/utils/stats/sample_data_provider.py similarity index 98% rename from tutorials/stats/3_sample_data_provider.py rename to utils/stats/sample_data_provider.py index 5c4e1262c..4a9dc1cbd 100644 --- a/tutorials/stats/3_sample_data_provider.py +++ b/utils/stats/sample_data_provider.py @@ -1,15 +1,12 @@ +#!/usr/bin/env python # %% [markdown] """ -# 3. Sample data provider - This script demonstrates various instrumentation capabilities. It also provides data for the dashboard emulating simultaneous queries to the service by multiple users. """ -# %pip install dff[stats] - # %% import random import asyncio From 532597e34888c29a65d8ce9c8ca1e84261b9d23a Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 22 Sep 2023 13:24:26 +0300 Subject: [PATCH 21/46] update links to avoid sphinx warnings --- docs/source/user_guides/superset_guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 42b3caaef..79d1c95a5 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -38,7 +38,7 @@ Collection procedure **Collecting data** Collecting data is done by means of instrumenting your conversational service before you run it. -DFF tutorials (`1`_, `2`_) +DFF tutorials (`1 `_, `2 `_) showcase all the steps needed to achieve that. We will run a special script in order to obtain richly-annotated sample data points to visualize. From 6ace1919b8393c4fca0f7822237ede2c35cce006 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 26 Sep 2023 13:47:20 +0300 Subject: [PATCH 22/46] update dashboard description; update tutorials --- .../dashboards/DFF_statistics_dashboard_1.yaml | 12 ++++++++---- dff/utils/testing/toy_script.py | 2 +- docs/source/user_guides/superset_guide.rst | 9 +++++---- tutorials/stats/1_extractor_functions.py | 2 +- tutorials/stats/2_pipeline_integration.py | 6 ++++-- utils/stats/sample_data_provider.py | 5 ++--- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index ce0e7819c..d4893be70 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -434,6 +434,9 @@ position: whether or not the path that users take on average deviates from the happy path that you plan for the users. + You can use the Dialog turn and User ID filters on the left + to only consider the requests produced by a particular user + or requests sent on a specific dialog turn.
@@ -523,12 +526,13 @@ position: The chart below shows, how frequently each of the graph edges was traversed by various users. - - Based on this information, you can determine which transitions inside the - dialog graph function + dialog graph function as intended. + + You can use the Dialog turn filter on the left + to only select a slice of transitions that only target a specific node. - as intended.' +
' height: 24 width: 12 parents: diff --git a/dff/utils/testing/toy_script.py b/dff/utils/testing/toy_script.py index b887a01f7..f035df047 100644 --- a/dff/utils/testing/toy_script.py +++ b/dff/utils/testing/toy_script.py @@ -98,7 +98,7 @@ TRANSITIONS: { "ask_about_breed": exact_match(Message(text="pereat")), "tell_fact_about_breed": exact_match(Message(text="bulldog")), - "ask_about_training": exact_match(Message(text="i do not known")), + "ask_about_training": exact_match(Message(text="I don't know")), }, }, "tell_fact_about_breed": { diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 79d1c95a5..98de4a706 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -38,7 +38,7 @@ Collection procedure **Collecting data** Collecting data is done by means of instrumenting your conversational service before you run it. -DFF tutorials (`1 `_, `2 `_) +DFF tutorials (`1 <../tutorials/tutorials.stats.1_extractor_functions.py>`_, `2 <../tutorials/tutorials.stats.2_pipeline_integration.py>`_) showcase all the steps needed to achieve that. We will run a special script in order to obtain richly-annotated sample data points to visualize. @@ -128,9 +128,10 @@ an easy and intuitive way to create your own charts and to customize the dashboa **Datasets** If you aim to create your own chart, Superset will prompt you to select a dataset to draw data from. -The current configuration provides two datasets `dff-node-stats` and `dff-final-nodes`. In most cases, -you will need to use `dff-node-stats`, since `dff-final-nodes` contains the same information, but only -aggregates terminal nodes. +The current configuration provides two datasets `dff-node-stats` and `dff-final-nodes`. +However, in most cases, you will need to use `dff-node-stats`, since `dff-final-nodes` contains the same information, but only +aggregates the labels of nodes visited at the end of dialog graph traversal, +i.e. nodes that terminate the dialog. `dff-nodes-stats` uses the following variables to store the data: diff --git a/tutorials/stats/1_extractor_functions.py b/tutorials/stats/1_extractor_functions.py index d91f049e9..6e853e407 100644 --- a/tutorials/stats/1_extractor_functions.py +++ b/tutorials/stats/1_extractor_functions.py @@ -103,7 +103,7 @@ async def heavy_service(ctx: Context): "fallback_label": ("greeting_flow", "fallback_node"), "components": [ heavy_service, - Service(handler=ACTOR, after_handler=[default_extractors.get_current_label]), + Service(handler=ACTOR, before_handler=[default_extractors.get_current_label]), ], } ) diff --git a/tutorials/stats/2_pipeline_integration.py b/tutorials/stats/2_pipeline_integration.py index de81a3593..a15eff470 100644 --- a/tutorials/stats/2_pipeline_integration.py +++ b/tutorials/stats/2_pipeline_integration.py @@ -90,11 +90,13 @@ async def heavy_service(ctx: Context): ), Service( handler=ACTOR, - before_handler=[default_extractors.get_timing_before], + before_handler=[ + default_extractors.get_current_label, + default_extractors.get_timing_before, + ], after_handler=[ get_service_state, default_extractors.get_timing_after, - default_extractors.get_current_label, ], ), ], diff --git a/utils/stats/sample_data_provider.py b/utils/stats/sample_data_provider.py index 4a9dc1cbd..6ed22f494 100644 --- a/utils/stats/sample_data_provider.py +++ b/utils/stats/sample_data_provider.py @@ -63,8 +63,8 @@ async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): Service( handler=ACTOR, before_handler=[ - default_extractors.get_timing_before, default_extractors.get_current_label, + default_extractors.get_timing_before, ], after_handler=[ default_extractors.get_timing_after, @@ -94,8 +94,7 @@ async def worker(queue: asyncio.Queue): label = ctx.last_label if ctx.last_label else pipeline.actor.fallback_label flow, node = label[:2] if [flow, node] == ["root", "fallback"]: - rand_interval = float(random.randint(0, 1)) + random.random() - await asyncio.sleep(rand_interval) + await asyncio.sleep(random.random() * 3) ctx = Context() flow, node = ["root", "start"] answers = list(MULTIFLOW_REQUEST_OPTIONS.get(flow, {}).get(node, [])) From c6f125907f0bb501e632b017fee5f15f05c50611 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 26 Sep 2023 14:44:54 +0300 Subject: [PATCH 23/46] update superset guide --- MANIFEST.in | 1 + docs/source/user_guides/superset_guide.rst | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 2bf8bfe27..11a3392f8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,6 +3,7 @@ include LICENSE include README.md graft dff/config/superset_dashboard include dff/context_storages/protocols.json +recursive-include utils * exclude makefile diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 98de4a706..5b6e81fc9 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -175,4 +175,13 @@ host machine, so that no information is lost when the Superset container or the The most convenient way to do that is to export the dashboard configuration as a whole. Navigate to the `Dashboards` section of the Superset application, locate your dashboard (named `DFF statistics` per default). -Then press the `export` button on the right and save the zip file to any convenient location. \ No newline at end of file +Then press the `export` button on the right and save the zip file to any convenient location. + +**Importing existing configuration files** + +If you need to restore your dashboard or update the configuration, you can import a configuration archive +that has been saved in the manner described above. + +Log in to Superset, open the `Dashboards` tab and press the import button on the right of the screen. +You will be prompted for the database password. If the database credentials match, +the updated dashboard will appear in the dashboard list. \ No newline at end of file From 17225e1797bdc091471032787af357e4dd6505ea Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 26 Sep 2023 15:20:48 +0300 Subject: [PATCH 24/46] update label extractor; add infile parameter to main; remove link to sample_data_provider --- .../dashboards/DFF_statistics_dashboard_1.yaml | 4 ++-- dff/stats/__main__.py | 16 ++++++++++++---- dff/stats/default_extractors.py | 6 +++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index d4893be70..c7ff2373d 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -411,8 +411,8 @@ position: **Note that the charts below will only display meaningful figures if the respective - annotation values have been collected. To get those, run the [Sample data - provider script](#).**' + annotation values have been collected. To get those, run the sample data + provider script located in the `utils/stats/` folder.**' height: 63 width: 12 parents: diff --git a/dff/stats/__main__.py b/dff/stats/__main__.py index 396273ea2..92ca42e87 100644 --- a/dff/stats/__main__.py +++ b/dff/stats/__main__.py @@ -73,6 +73,7 @@ def main(parsed_args: Optional[argparse.Namespace] = None): parser.add_argument("-dn", "--db.name", help="Name of the database.") parser.add_argument("-dt", "--db.table", default="otel_logs", help="Name of the table.") parser.add_argument("-o", "--outfile", help="Optionally persist the configuration as a zip file.") + parser.add_argument("-i", "--infile", help="Configuration zip file to import.") parser.add_argument("-H", "--host", default="localhost", help="Superset host") parser.add_argument("-p", "--port", default="8088", help="Superset port.") parser.add_argument("-U", "--username", required=True, help="Superset user.") @@ -100,11 +101,18 @@ def main(parsed_args: Optional[argparse.Namespace] = None): if parsed_args is None: parsed_args = parser.parse_args(sys.argv[1:]) - outfile = make_zip_config(parsed_args) - import_dashboard(parsed_args, zip_file=str(outfile)) + file = None + use_infile = hasattr(parsed_args, "infile") and parsed_args.infile is not None + use_outfile = hasattr(parsed_args, "outfile") and parsed_args.outfile is not None + if not use_infile: + file = make_zip_config(parsed_args) + else: + file = parsed_args.infile - if not hasattr(parsed_args, "outfile") or parsed_args.outfile is None: - outfile.unlink() + import_dashboard(parsed_args, zip_file=str(file)) + + if not use_infile and not use_outfile: + file.unlink() if __name__ == "__main__": diff --git a/dff/stats/default_extractors.py b/dff/stats/default_extractors.py index d39d503c6..bcf63c781 100644 --- a/dff/stats/default_extractors.py +++ b/dff/stats/default_extractors.py @@ -13,18 +13,18 @@ from datetime import datetime from dff.script import Context -from dff.pipeline import ExtraHandlerRuntimeInfo +from dff.pipeline import ExtraHandlerRuntimeInfo, Pipeline from .utils import get_wrapper_field -async def get_current_label(ctx: Context, _, info: ExtraHandlerRuntimeInfo): +async def get_current_label(ctx: Context, pipeline: Pipeline, info: ExtraHandlerRuntimeInfo): """ Extract the current label on each turn. This function is required for running the dashboard with the default configuration. """ last_label = ctx.last_label if last_label is None: - return {"flow": None, "node": None, "label": None} + last_label = pipeline.actor.start_label[:2] return {"flow": last_label[0], "node": last_label[1], "label": ": ".join(last_label)} From d355290e9d0f5df0e4aa27f02458ffee58451a6d Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 26 Sep 2023 16:08:10 +0300 Subject: [PATCH 25/46] update tests --- tests/stats/test_defaults.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/stats/test_defaults.py b/tests/stats/test_defaults.py index 11c525723..7ff3cd68c 100644 --- a/tests/stats/test_defaults.py +++ b/tests/stats/test_defaults.py @@ -6,6 +6,7 @@ except ImportError: pytest.skip(allow_module_level=True, reason="One of the Opentelemetry packages is missing.") +import importlib from dff.script import Context from dff.pipeline.types import ExtraHandlerRuntimeInfo, ServiceRuntimeInfo from dff.stats import default_extractors @@ -20,7 +21,15 @@ ], ) async def test_get_current_label(context: Context, expected: set): - result = await default_extractors.get_current_label(context, None, {"component": {"path": "."}}) + example_module = importlib.import_module(f"tutorials.stats.1_extractor_functions") + runtime_info = ExtraHandlerRuntimeInfo( + func=lambda x: x, + stage="BEFORE", + component=ServiceRuntimeInfo( + path=".", name=".", timeout=None, asynchronous=False, execution_state={".": "FINISHED"} + ), + ) + result = await default_extractors.get_current_label(context, example_module.pipeline, runtime_info) assert expected.intersection(set(result.items())) == expected @@ -35,6 +44,7 @@ async def test_get_current_label(context: Context, expected: set): async def test_otlp_integration(context, expected, tracer_exporter_and_provider, log_exporter_and_provider): _, tracer_provider = tracer_exporter_and_provider log_exporter, logger_provider = log_exporter_and_provider + example_module = importlib.import_module(f"tutorials.stats.1_extractor_functions") instrumentor = OtelInstrumentor() if instrumentor.is_instrumented_by_opentelemetry: instrumentor.uninstrument() @@ -46,7 +56,7 @@ async def test_otlp_integration(context, expected, tracer_exporter_and_provider, path=".", name=".", timeout=None, asynchronous=False, execution_state={".": "FINISHED"} ), ) - _ = await default_extractors.get_current_label(context, None, runtime_info) + _ = await default_extractors.get_current_label(context, example_module.pipeline, runtime_info) tracer_provider.force_flush() logger_provider.force_flush() assert len(log_exporter.get_finished_logs()) > 0 From eddc688912c1f3d07bf5f092f7d259e4dd7c60d3 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 26 Sep 2023 16:12:40 +0300 Subject: [PATCH 26/46] update format --- tests/stats/test_defaults.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/stats/test_defaults.py b/tests/stats/test_defaults.py index 7ff3cd68c..d565efcdd 100644 --- a/tests/stats/test_defaults.py +++ b/tests/stats/test_defaults.py @@ -21,7 +21,7 @@ ], ) async def test_get_current_label(context: Context, expected: set): - example_module = importlib.import_module(f"tutorials.stats.1_extractor_functions") + example_module = importlib.import_module("tutorials.stats.1_extractor_functions") runtime_info = ExtraHandlerRuntimeInfo( func=lambda x: x, stage="BEFORE", @@ -44,7 +44,7 @@ async def test_get_current_label(context: Context, expected: set): async def test_otlp_integration(context, expected, tracer_exporter_and_provider, log_exporter_and_provider): _, tracer_provider = tracer_exporter_and_provider log_exporter, logger_provider = log_exporter_and_provider - example_module = importlib.import_module(f"tutorials.stats.1_extractor_functions") + example_module = importlib.import_module("tutorials.stats.1_extractor_functions") instrumentor = OtelInstrumentor() if instrumentor.is_instrumented_by_opentelemetry: instrumentor.uninstrument() From 3c1551130c815562e10251eac2a55f20fcfb61b6 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 5 Oct 2023 20:44:49 +0300 Subject: [PATCH 27/46] minor doc improvements --- .../dashboards/DFF_statistics_dashboard_1.yaml | 14 +++++--------- docs/source/user_guides/superset_guide.rst | 4 ++-- tutorials/stats/1_extractor_functions.py | 3 ++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index c7ff2373d..90b002427 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -430,14 +430,10 @@ position: This bar chart aggregates node labels over dialog turns. Not only does this - show the average estimated dialog length, but it also allows you to observe - whether or not the path that users take on average deviates from the happy + show the average dialog length, but it also allows you to observe + whether the path that users take on average deviates from the happy path that you plan for the users. - You can use the Dialog turn and User ID filters on the left - to only consider the requests produced by a particular user - or requests sent on a specific dialog turn. -
' @@ -524,13 +520,13 @@ position: code: '## Transitions distribution - The chart below shows, how frequently each of the graph edges was traversed + The chart below shows how frequently each of the graph edges is traversed by various users. Based on this information, you can determine which transitions inside the dialog graph function as intended. - You can use the Dialog turn filter on the left - to only select a slice of transitions that only target a specific node. + You can use the `Node` filter on the left + to select a slice of transitions that target a specific node.
' height: 24 diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 5b6e81fc9..47feead3c 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -129,7 +129,7 @@ an easy and intuitive way to create your own charts and to customize the dashboa If you aim to create your own chart, Superset will prompt you to select a dataset to draw data from. The current configuration provides two datasets `dff-node-stats` and `dff-final-nodes`. -However, in most cases, you will need to use `dff-node-stats`, since `dff-final-nodes` contains the same information, but only +However, in most cases, you would use `dff-node-stats` since `dff-final-nodes` contains the same information, but only aggregates the labels of nodes visited at the end of dialog graph traversal, i.e. nodes that terminate the dialog. @@ -180,7 +180,7 @@ Then press the `export` button on the right and save the zip file to any conveni **Importing existing configuration files** If you need to restore your dashboard or update the configuration, you can import a configuration archive -that has been saved in the manner described above. +that has been saved in the manner described below. Log in to Superset, open the `Dashboards` tab and press the import button on the right of the screen. You will be prompted for the database password. If the database credentials match, diff --git a/tutorials/stats/1_extractor_functions.py b/tutorials/stats/1_extractor_functions.py index 6e853e407..3afbbe8a3 100644 --- a/tutorials/stats/1_extractor_functions.py +++ b/tutorials/stats/1_extractor_functions.py @@ -7,7 +7,8 @@ Statistics are collected from pipeline services by extractor functions that report the state of one or more pipeline components. The `stats` module provides several default extractors, but users are free to define their own -extractor functions. +extractor functions. You can find API reference for default extractors +[here](%doclink(api,stats.default_extractors)). It is a preferred practice to define extractors as asynchronous functions. Extractors need to have the following uniform signature: From 457a50c32270996c8940a6cf7ffc0b9531840c9b Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 6 Oct 2023 16:02:42 +0300 Subject: [PATCH 28/46] update dashboard datasource config --- dff/stats/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/stats/cli.py b/dff/stats/cli.py index d47f38176..f032b2a86 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -70,7 +70,7 @@ {table}.TraceId as trace_id, otel_traces.TraceId\nFROM {table}, otel_traces WHERE {table}.TraceId = otel_traces.TraceId - ORDER BY context_id, request_id + ORDER BY data_key, context_id, request_id ) SELECT context_id, request_id, start_time, @@ -114,7 +114,7 @@ ) SELECT DISTINCT LogAttributes['context_id'] AS context_id, LogAttributes['request_id'] AS request_id, -{table}.Timestamp AS start_time, +otel_traces.Timestamp AS start_time, {lblfield} AS label, {flowfield} AS flow_label, {nodefield} AS node_label From a470da32c4eb0c0d1a09f57ecd6bfb69bfe67924 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 10 Oct 2023 17:01:31 +0300 Subject: [PATCH 29/46] add dff_stats dataset; link charts to dff_stats dataset --- .../Current_topic_slot_bar_chart_4.yaml | 19 ++- ...Current_topic_time_series_bar_chart_2.yaml | 19 ++- .../charts/Rating_slot_line_chart_1.yaml | 10 +- .../charts/Requests_17.yaml | 40 +++-- .../charts/Responses_16.yaml | 40 +++-- .../superset_dashboard/charts/Table_14.yaml | 34 ++-- .../datasets/dff_database/dff_node_stats.yaml | 9 +- .../datasets/dff_database/dff_stats.yaml | 155 ++++++++++++++++++ dff/stats/cli.py | 50 +++--- dff/stats/default_extractors.py | 5 + tutorials/stats/1_extractor_functions.py | 2 +- tutorials/stats/2_pipeline_integration.py | 6 +- 12 files changed, 285 insertions(+), 104 deletions(-) create mode 100644 dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml diff --git a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml index f8fbc5b76..57deb8a71 100644 --- a/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml +++ b/dff/config/superset_dashboard/charts/Current_topic_slot_bar_chart_4.yaml @@ -4,7 +4,7 @@ certified_by: null certification_details: null viz_type: dist_bar params: - datasource: 2__table + datasource: 3__table viz_type: dist_bar slice_id: 6 granularity_sqla: start_time @@ -36,9 +36,10 @@ params: groupby: - request_id columns: - - label: My column + - expressionType: SQL + label: My column sqlExpression: JSON_VALUE(data, '$.current_topic') - expressionType: SQL + datasourceWarning: false row_limit: 10000 order_desc: true color_scheme: echarts4Colors @@ -57,15 +58,15 @@ params: extra_form_data: {} dashboards: - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"having":"","where":"(JSON_VALUE(data, - ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":["request_id",{"label":"My - column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","expressionType":"SQL"}],"metrics":["count"],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"2__table","viz_type":"dist_bar","slice_id":6,"granularity_sqla":"start_time","time_range":"No + ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":["request_id",{"expressionType":"SQL","label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","datasourceWarning":false}],"metrics":["count"],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"3__table","viz_type":"dist_bar","slice_id":6,"granularity_sqla":"start_time","time_range":"No filter","metrics":["count"],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_sz14lhn7d1d_c0zqn5dpgk","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_945dhn41x2m_sci7gkxy7o","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, - ''$.current_topic'') <> ''''","subject":null}],"groupby":["request_id"],"columns":[{"label":"My - column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","expressionType":"SQL"}],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":false,"y_axis_format":"SMART_NUMBER","y_axis_label":"Topic + ''$.current_topic'') <> ''''","subject":null}],"groupby":["request_id"],"columns":[{"expressionType":"SQL","label":"My + column","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')","datasourceWarning":false}],"row_limit":10000,"order_desc":true,"color_scheme":"echarts4Colors","show_legend":true,"rich_tooltip":true,"bar_stacked":true,"order_bars":false,"y_axis_format":"SMART_NUMBER","y_axis_label":"Topic counts","y_axis_bounds":[null,null],"x_axis_label":"Dialog turn","bottom_margin":"auto","x_ticks_layout":"auto","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: a70c05d0-770b-4068-a55d-934283f5b1bb version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml b/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml index 6d34316be..26ad821d3 100644 --- a/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml +++ b/dff/config/superset_dashboard/charts/Current_topic_time_series_bar_chart_2.yaml @@ -4,16 +4,17 @@ certified_by: null certification_details: null viz_type: echarts_timeseries_bar params: - datasource: 2__table + datasource: 3__table viz_type: echarts_timeseries_bar - slice_id: 15 + slice_id: 10 granularity_sqla: start_time time_grain_sqla: PT1M time_range: No filter metrics: - count groupby: - - expressionType: SQL + - datasourceWarning: false + expressionType: SQL label: context_id sqlExpression: JSON_VALUE(data, '$.current_topic') adhoc_filters: @@ -70,16 +71,16 @@ params: extra_form_data: {} dashboards: - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(JSON_VALUE(data, - ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, - ''$.current_topic'')"}],"metrics":["count"],"orderby":[["count",false]],"annotation_layers":[],"row_limit":10000,"series_columns":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, - ''$.current_topic'')"}],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["context_id"],"aggregates":{"count":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"count":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_bar","slice_id":15,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No - filter","metrics":["count"],"groupby":[{"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'') <> '''')"},"applied_time_extras":{},"columns":[{"datasourceWarning":false,"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'')"}],"metrics":["count"],"orderby":[["count",false]],"annotation_layers":[],"row_limit":10000,"series_columns":[{"datasourceWarning":false,"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, + ''$.current_topic'')"}],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["context_id"],"aggregates":{"count":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"count":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"3__table","viz_type":"echarts_timeseries_bar","slice_id":10,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No + filter","metrics":["count"],"groupby":[{"datasourceWarning":false,"expressionType":"SQL","label":"context_id","sqlExpression":"JSON_VALUE(data, ''$.current_topic'')"}],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_8tft5fr07ea_urtdezftgn","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_4ffdpny1zzm_vmlo11yw7i","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, ''$.current_topic'') <> ''''","subject":null}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title":"Time axis","x_axis_title_margin":30,"y_axis_title":"Value counts over time","y_axis_title_margin":30,"y_axis_title_position":"Left","color_scheme":"echarts4Colors","show_value":false,"stack":true,"only_total":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipSortByMetric":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: f8215b4d-cdaf-489a-90b2-040da840ab35 version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml b/dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml index cc13f303d..3c00dc2ca 100644 --- a/dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml +++ b/dff/config/superset_dashboard/charts/Rating_slot_line_chart_1.yaml @@ -4,9 +4,9 @@ certified_by: null certification_details: null viz_type: echarts_timeseries_line params: - datasource: 2__table + datasource: 3__table viz_type: echarts_timeseries_line - slice_id: 17 + slice_id: 7 granularity_sqla: start_time time_grain_sqla: PT1M time_range: No filter @@ -73,14 +73,14 @@ params: extra_form_data: {} dashboards: - 1 -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_slots"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":"(JSON_VALUE(data, ''$.rating'') <> '''')"},"applied_time_extras":{},"columns":[],"metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS Int16))"}],"orderby":[[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS Int16))"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":[],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":[],"aggregates":{"AVG(CAST(JSON_VALUE(data, - ''$.rating'') AS...":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"2__table","viz_type":"echarts_timeseries_line","slice_id":17,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No + ''$.rating'') AS...":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"3__table","viz_type":"echarts_timeseries_line","slice_id":7,"granularity_sqla":"start_time","time_grain_sqla":"PT1M","time_range":"No filter","metrics":[{"aggregate":null,"column":null,"datasourceWarning":false,"expressionType":"SQL","hasCustomLabel":false,"label":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS...","optionName":"metric_00oy6lz4f1x8m_ogwvyq0hxx","sqlExpression":"AVG(CAST(JSON_VALUE(data, ''$.rating'') AS Int16))"}],"groupby":[],"adhoc_filters":[{"clause":"WHERE","comparator":"get_slots","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_7obcf0exa9_1e58m260tq5","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"},{"clause":"WHERE","comparator":null,"datasourceWarning":false,"expressionType":"SQL","filterOptionName":"filter_0sg816yobyac_obqceo13prc","isExtra":false,"isNew":false,"operator":null,"sqlExpression":"JSON_VALUE(data, @@ -89,4 +89,4 @@ query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{ cache_timeout: null uuid: 128e1da2-1efd-433d-9b93-a07de175e2bc version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/charts/Requests_17.yaml b/dff/config/superset_dashboard/charts/Requests_17.yaml index a9289f7e2..9881f448b 100644 --- a/dff/config/superset_dashboard/charts/Requests_17.yaml +++ b/dff/config/superset_dashboard/charts/Requests_17.yaml @@ -4,8 +4,9 @@ certified_by: null certification_details: null viz_type: table params: - datasource: 2__table + datasource: 3__table viz_type: table + slice_id: 8 granularity_sqla: start_time time_grain_sqla: P1D time_range: No filter @@ -15,22 +16,23 @@ params: - context_id - request_id - start_time - - label: data + - expressionType: SQL + label: data sqlExpression: JSON_VALUE(data, '$.last_request') - expressionType: SQL + datasourceWarning: false percent_metrics: [] adhoc_filters: - - expressionType: SIMPLE - subject: data_key - operator: == - operatorId: EQUALS + - clause: WHERE comparator: get_last_request - clause: WHERE - sqlExpression: null - isExtra: false - isNew: false datasourceWarning: false + expressionType: SIMPLE filterOptionName: filter_4amlkzz0hd3_exx83iz5rof + isExtra: false + isNew: false + operator: == + operatorId: EQUALS + sqlExpression: null + subject: data_key order_by_cols: [] row_limit: 1000 server_page_length: 10 @@ -43,13 +45,15 @@ params: columnWidth: 150 truncateLongCells: true extra_form_data: {} - dashboards: [] -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_request"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_request'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No - filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_request'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_request","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + dashboards: + - 1 +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_request"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"expressionType":"SQL","label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_request'')","datasourceWarning":false}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"3__table","viz_type":"table","slice_id":8,"granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No + filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"expressionType":"SQL","label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_request'')","datasourceWarning":false}],"percent_metrics":[],"adhoc_filters":[{"clause":"WHERE","comparator":"get_last_request","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_4amlkzz0hd3_exx83iz5rof","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y + %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"columnWidth":150,"truncateLongCells":true}},"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 45ef67db-d33d-49f5-8d46-1f0fa518eaac version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/charts/Responses_16.yaml b/dff/config/superset_dashboard/charts/Responses_16.yaml index c6ac78b70..02349a9f1 100644 --- a/dff/config/superset_dashboard/charts/Responses_16.yaml +++ b/dff/config/superset_dashboard/charts/Responses_16.yaml @@ -4,8 +4,9 @@ certified_by: null certification_details: null viz_type: table params: - datasource: 2__table + datasource: 3__table viz_type: table + slice_id: 15 granularity_sqla: start_time time_grain_sqla: P1D time_range: No filter @@ -15,22 +16,23 @@ params: - context_id - request_id - start_time - - label: data + - expressionType: SQL + label: data sqlExpression: JSON_VALUE(data, '$.last_response') - expressionType: SQL + datasourceWarning: false percent_metrics: [] adhoc_filters: - - expressionType: SIMPLE - subject: data_key - operator: == - operatorId: EQUALS + - clause: WHERE comparator: get_last_response - clause: WHERE - sqlExpression: null - isExtra: false - isNew: false datasourceWarning: false + expressionType: SIMPLE filterOptionName: filter_m3nzyr545di_lxjaivcal1 + isExtra: false + isNew: false + operator: == + operatorId: EQUALS + sqlExpression: null + subject: data_key order_by_cols: [] row_limit: 1000 server_page_length: 10 @@ -43,13 +45,15 @@ params: columnWidth: 150 truncateLongCells: true extra_form_data: {} - dashboards: [] -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_response"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_response'')","expressionType":"SQL"}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"2__table","viz_type":"table","granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No - filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"label":"data","sqlExpression":"JSON_VALUE(data, - ''$.last_response'')","expressionType":"SQL"}],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"data_key","operator":"==","operatorId":"EQUALS","comparator":"get_last_response","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m3nzyr545di_lxjaivcal1"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"truncateLongCells":true,"columnWidth":150}},"extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + dashboards: + - 1 +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[{"col":"data_key","op":"==","val":"get_last_response"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":["context_id","request_id","start_time",{"expressionType":"SQL","label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_response'')","datasourceWarning":false}],"orderby":[],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"3__table","viz_type":"table","slice_id":15,"granularity_sqla":"start_time","time_grain_sqla":"P1D","time_range":"No + filter","query_mode":"raw","groupby":[],"all_columns":["context_id","request_id","start_time",{"expressionType":"SQL","label":"data","sqlExpression":"JSON_VALUE(data, + ''$.last_response'')","datasourceWarning":false}],"percent_metrics":[],"adhoc_filters":[{"clause":"WHERE","comparator":"get_last_response","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_m3nzyr545di_lxjaivcal1","isExtra":false,"isNew":false,"operator":"==","operatorId":"EQUALS","sqlExpression":null,"subject":"data_key"}],"order_by_cols":[],"row_limit":1000,"server_page_length":10,"include_time":false,"order_desc":true,"table_timestamp_format":"%d-%m-%Y + %H:%M:%S","show_cell_bars":true,"color_pn":true,"column_config":{"data":{"columnWidth":150,"truncateLongCells":true}},"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 7844eb6d-4fce-44cf-8994-fb61a221a2ab version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/charts/Table_14.yaml b/dff/config/superset_dashboard/charts/Table_14.yaml index 00c9ced03..fade8e8c9 100644 --- a/dff/config/superset_dashboard/charts/Table_14.yaml +++ b/dff/config/superset_dashboard/charts/Table_14.yaml @@ -4,33 +4,35 @@ certified_by: null certification_details: null viz_type: table params: - adhoc_filters: [] - all_columns: [] - color_pn: true datasource: 3__table - extra_form_data: {} + viz_type: table + slice_id: 16 granularity_sqla: start_time + time_grain_sqla: null + time_range: No filter + query_mode: aggregate groupby: - context_id - start_time - data_key - data - order_by_cols: [] - order_desc: false + all_columns: [] percent_metrics: [] - query_mode: aggregate + adhoc_filters: [] + order_by_cols: [] row_limit: 10000 server_page_length: 10 - show_cell_bars: true - slice_id: 14 + order_desc: false table_timestamp_format: smart_date - time_grain_sqla: null - time_range: No filter - viz_type: table -query_context: '{"datasource":{"id":2,"type":"table"},"force":false,"queries":[{"time_range":"No - filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":["context_id","start_time","data_key","data"],"metrics":[],"orderby":[],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":false,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"adhoc_filters":[],"all_columns":[],"color_pn":true,"datasource":"2__table","extra_form_data":{},"granularity_sqla":"start_time","groupby":["context_id","start_time","data_key","data"],"order_by_cols":[],"order_desc":false,"percent_metrics":[],"query_mode":"aggregate","row_limit":10000,"server_page_length":10,"show_cell_bars":true,"slice_id":14,"table_timestamp_format":"smart_date","time_grain_sqla":null,"time_range":"No - filter","viz_type":"table","force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' + show_cell_bars: true + color_pn: true + extra_form_data: {} + dashboards: + - 1 +query_context: '{"datasource":{"id":3,"type":"table"},"force":false,"queries":[{"time_range":"No + filter","granularity":"start_time","filters":[],"extras":{"time_grain_sqla":null,"having":"","where":""},"applied_time_extras":{},"columns":["context_id","start_time","data_key","data"],"metrics":[],"orderby":[],"annotation_layers":[],"row_limit":10000,"series_limit":0,"order_desc":false,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[]}],"form_data":{"datasource":"3__table","viz_type":"table","slice_id":16,"granularity_sqla":"start_time","time_grain_sqla":null,"time_range":"No + filter","query_mode":"aggregate","groupby":["context_id","start_time","data_key","data"],"all_columns":[],"percent_metrics":[],"adhoc_filters":[],"order_by_cols":[],"row_limit":10000,"server_page_length":10,"order_desc":false,"table_timestamp_format":"smart_date","show_cell_bars":true,"color_pn":true,"extra_form_data":{},"dashboards":[1],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}' cache_timeout: null uuid: 38d353dc-c0ef-41a0-97c7-3dcbebab9e02 version: 1.0.0 -dataset_uuid: fda98ab8-f550-45f1-9ded-0113f3e67260 +dataset_uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index 60a97ea13..2b87aee26 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -11,10 +11,11 @@ sql: "\nWITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id' \ data_key,\n otel_logs.Body as data,\n JSON_VALUE(otel_logs.Body, '$.label')\ \ as label,\n JSON_VALUE(otel_logs.Body, '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body,\ \ '$.node') as node_label,\n otel_logs.TraceId as trace_id,\n otel_traces.TraceId\n\ - FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId\n\ - \ ORDER BY context_id, request_id\n) SELECT context_id,\n request_id,\n \ - \ start_time,\n data_key,\n data,\n label,\n neighbor(label, -1) as\ - \ prev_label,\n, neighbor(flow_label, -1) as prev_flow, flow_label,\n node_label\nFROM main\n" + FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId and\ + \ data_key = 'get_current_label'\n ORDER BY context_id, request_id\n) SELECT\ + \ context_id,\n request_id,\n start_time,\n data_key,\n data,\n label,\n\ + \ neighbor(label, -1) as prev_label,\n neighbor(flow_label, -1) as prev_flow,\n\ + \ flow_label,\n node_label\nFROM main\n" params: null template_params: null filter_select_enabled: false diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml new file mode 100644 index 000000000..142a2ccc0 --- /dev/null +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml @@ -0,0 +1,155 @@ +table_name: dff_stats +main_dttm_col: null +description: null +default_endpoint: null +offset: 0 +cache_timeout: null +schema: test +sql: "WITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id'] as\ + \ context_id,\n otel_logs.LogAttributes['request_id'] as request_id,\n toDateTime(otel_traces.Timestamp)\ + \ as start_time,\n otel_traces.SpanName as data_key,\n otel_logs.Body as data,\n\ + \ JSON_VALUE(otel_logs.Body, '$.label') as label,\n JSON_VALUE(otel_logs.Body,\ + \ '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body, '$.node') as node_label,\n\ + \ otel_logs.TraceId as trace_id,\n otel_traces.TraceId\nFROM otel_logs, otel_traces\n\ + \ WHERE otel_logs.TraceId = otel_traces.TraceId\n ORDER BY data_key, context_id,\ + \ request_id\n) SELECT context_id,\n request_id,\n start_time,\n data_key,\n\ + \ data,\n label,\n neighbor(label, -1) as prev_label,\n neighbor(flow_label,\ + \ -1) as prev_flow,\n flow_label,\n node_label\nFROM main" +params: null +template_params: null +filter_select_enabled: false +fetch_values_predicate: null +extra: null +uuid: 8ba2e188-2bf8-4809-a5ee-2477a539d493 +metrics: +- metric_name: count + verbose_name: null + metric_type: null + expression: count(*) + description: null + d3format: null + extra: {} + warning_text: null +columns: +- column_name: data_key + verbose_name: null + is_dttm: false + is_active: true + type: LowCardinality(String) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: start_time + verbose_name: null + is_dttm: true + is_active: true + type: DateTime + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: node_label + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: prev_label + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: flow_label + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: context_id + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: request_id + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: prev_flow + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: data + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +- column_name: label + verbose_name: null + is_dttm: false + is_active: true + type: String + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + extra: {} +version: 1.0.0 +database_uuid: ee32f76e-55e3-483a-935a-22d03072db23 diff --git a/dff/stats/cli.py b/dff/stats/cli.py index f032b2a86..753e6af33 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -4,6 +4,7 @@ This modules defines commands that can be called via the command line interface. """ +from uuid import uuid4 import tempfile import shutil import sys @@ -69,8 +70,8 @@ {nodefield} as node_label, {table}.TraceId as trace_id, otel_traces.TraceId\nFROM {table}, otel_traces - WHERE {table}.TraceId = otel_traces.TraceId - ORDER BY data_key, context_id, request_id + WHERE {table}.TraceId = otel_traces.TraceId and data_key = 'get_current_label' + ORDER BY context_id, request_id ) SELECT context_id, request_id, start_time, @@ -83,28 +84,31 @@ node_label FROM main """ -DFF_ACYCLIC_NODES_STATEMENT = """ +DFF_STATS_STATEMENT = """ WITH main AS ( SELECT DISTINCT {table}.LogAttributes['context_id'] as context_id, {table}.LogAttributes['request_id'] as request_id, - {table}.Timestamp as timestamp, - {lblfield} as label\nFROM {table} - INNER JOIN -( - WITH helper AS ( - SELECT DISTINCT {table}.LogAttributes['context_id'] as context_id, - {table}.LogAttributes['request_id'] as request_id, - {lblfield} as label - FROM {table} - ) - SELECT context_id FROM helper - GROUP BY context_id - HAVING COUNT(context_id) = COUNT(DISTINCT label) -) as plain_ctx -ON plain_ctx.context_id = context_id -ORDER by context_id, request_id -) -SELECT * FROM main + toDateTime(otel_traces.Timestamp) as start_time, + otel_traces.SpanName as data_key, + {table}.Body as data, + {lblfield} as label, + {flowfield} as flow_label, + {nodefield} as node_label, + {table}.TraceId as trace_id, + otel_traces.TraceId\nFROM {table}, otel_traces + WHERE {table}.TraceId = otel_traces.TraceId + ORDER BY data_key, context_id, request_id +) SELECT context_id, + request_id, + start_time, + data_key, + data, + label, + {label_lag} as prev_label, + {flow_lag} as prev_flow, + flow_label, + node_label +FROM main """ DFF_FINAL_NODES_STATEMENT = """ WITH main AS ( @@ -128,7 +132,7 @@ """ SQL_STATEMENT_MAPPING = { - "dff_acyclic_nodes.yaml": DFF_ACYCLIC_NODES_STATEMENT, + "dff_stats.yaml": DFF_STATS_STATEMENT, "dff_node_stats.yaml": DFF_NODE_STATS_STATEMENT, "dff_final_nodes.yaml": DFF_FINAL_NODES_STATEMENT, } @@ -184,7 +188,7 @@ def make_zip_config(parsed_args: argparse.Namespace) -> Path: if hasattr(parsed_args, "outfile") and parsed_args.outfile: outfile_name = parsed_args.outfile else: - outfile_name = "temp.zip" + outfile_name = f"config_{str(uuid4())}.zip" file_conf = OmegaConf.load(parsed_args.file) sys.argv = [__file__] + [f"{key}={value}" for key, value in parsed_args.__dict__.items() if value] diff --git a/dff/stats/default_extractors.py b/dff/stats/default_extractors.py index bcf63c781..f90a3e3ad 100644 --- a/dff/stats/default_extractors.py +++ b/dff/stats/default_extractors.py @@ -21,6 +21,11 @@ async def get_current_label(ctx: Context, pipeline: Pipeline, info: ExtraHandler """ Extract the current label on each turn. This function is required for running the dashboard with the default configuration. + + .. note:: + + Preferrably, it needs to be invoked as `after_handler` of the `Actor` service. + """ last_label = ctx.last_label if last_label is None: diff --git a/tutorials/stats/1_extractor_functions.py b/tutorials/stats/1_extractor_functions.py index 3afbbe8a3..f8ba327c0 100644 --- a/tutorials/stats/1_extractor_functions.py +++ b/tutorials/stats/1_extractor_functions.py @@ -104,7 +104,7 @@ async def heavy_service(ctx: Context): "fallback_label": ("greeting_flow", "fallback_node"), "components": [ heavy_service, - Service(handler=ACTOR, before_handler=[default_extractors.get_current_label]), + Service(handler=ACTOR, after_handler=[default_extractors.get_current_label]), ], } ) diff --git a/tutorials/stats/2_pipeline_integration.py b/tutorials/stats/2_pipeline_integration.py index a15eff470..53c3b4b3a 100644 --- a/tutorials/stats/2_pipeline_integration.py +++ b/tutorials/stats/2_pipeline_integration.py @@ -72,6 +72,10 @@ async def heavy_service(ctx: Context): the pre-service and post-service states of the context to measure the performance of various components, etc. +Some extractors, like `get_current_label`, have restrictions in terms of their run stage: +for instance, `get_current_label` needs to only be used as an `after_handler` +to function correctly. + """ # %% pipeline = Pipeline.from_dict( @@ -91,11 +95,11 @@ async def heavy_service(ctx: Context): Service( handler=ACTOR, before_handler=[ - default_extractors.get_current_label, default_extractors.get_timing_before, ], after_handler=[ get_service_state, + default_extractors.get_current_label, default_extractors.get_timing_after, ], ), From 49d2e8a36926559baa977b50f8aafff2f80f69fc Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 10 Oct 2023 17:36:40 +0300 Subject: [PATCH 30/46] update tests and documentation to reflect config changes --- docs/source/user_guides/superset_guide.rst | 9 ++++++--- tests/stats/test_main.py | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 47feead3c..c5e64ea56 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -128,9 +128,12 @@ an easy and intuitive way to create your own charts and to customize the dashboa **Datasets** If you aim to create your own chart, Superset will prompt you to select a dataset to draw data from. -The current configuration provides two datasets `dff-node-stats` and `dff-final-nodes`. -However, in most cases, you would use `dff-node-stats` since `dff-final-nodes` contains the same information, but only -aggregates the labels of nodes visited at the end of dialog graph traversal, +The current configuration provides three datasets `dff-node-stats`, `dff-stats`, and `dff-final-nodes`. +However, in most cases, you would use `dff-stats` or `dff-node-stats`. The former contains all data points, +while the latter only includes the logs produced by `get_current_label` extractor +(`see the API reference <../apiref/dff.stats.default_extractors.html#dff.stats.default_extractors.get_current_label>`_). +`dff-final-nodes` contains the same information as the said datasources, +but only aggregates the labels of nodes visited at the end of dialog graph traversal, i.e. nodes that terminate the dialog. `dff-nodes-stats` uses the following variables to store the data: diff --git a/tests/stats/test_main.py b/tests/stats/test_main.py index f6fcf0da0..164bc5596 100644 --- a/tests/stats/test_main.py +++ b/tests/stats/test_main.py @@ -76,12 +76,13 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): assert dashboard_json["result"]["dashboard_title"] == "DFF statistics dashboard" datasets_result = session.get(datasets_url, headers=headers) datasets_json = datasets_result.json() - assert datasets_json["count"] == 2 - assert datasets_json["ids"] == [1, 2] - assert [item["id"] for item in datasets_json["result"]] == [1, 2] + assert datasets_json["count"] == 3 + assert datasets_json["ids"] == [1, 2, 3] + assert [item["id"] for item in datasets_json["result"]] == [1, 2, 3] assert sorted([item["table_name"] for item in datasets_json["result"]]) == [ "dff_final_nodes", "dff_node_stats", + "dff_stats" ] charts_result = session.get(charts_url, headers=headers) charts_json = charts_result.json() From ed2db47dd7255ba15d921f574d71a08c49ad856d Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 10 Oct 2023 17:40:45 +0300 Subject: [PATCH 31/46] update formatting --- tests/stats/test_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stats/test_main.py b/tests/stats/test_main.py index 164bc5596..c6539343e 100644 --- a/tests/stats/test_main.py +++ b/tests/stats/test_main.py @@ -82,7 +82,7 @@ def dashboard_display_test(args: Namespace, session, headers, base_url: str): assert sorted([item["table_name"] for item in datasets_json["result"]]) == [ "dff_final_nodes", "dff_node_stats", - "dff_stats" + "dff_stats", ] charts_result = session.get(charts_url, headers=headers) charts_json = charts_result.json() From d9265ca0154737967b3e260a81e4d78f35f3246e Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 10 Oct 2023 19:20:51 +0300 Subject: [PATCH 32/46] add the test configuration file --- dff/utils/docker/dockerfile_stats | 1 + dff/utils/docker/superset_config_docker.py | 30 ++++++++++++++++++++++ docker-compose.yml | 5 ++++ 3 files changed, 36 insertions(+) create mode 100644 dff/utils/docker/superset_config_docker.py diff --git a/dff/utils/docker/dockerfile_stats b/dff/utils/docker/dockerfile_stats index 5017fd975..e7f04022a 100644 --- a/dff/utils/docker/dockerfile_stats +++ b/dff/utils/docker/dockerfile_stats @@ -2,5 +2,6 @@ FROM apache/superset:2.1.0rc1 USER root RUN cd /app && pip install .[clickhouse] COPY entrypoint_stats.sh /app/docker/ +COPY superset_config_docker.py /app/pythonpath/ USER superset ENTRYPOINT ["/bin/bash","/app/docker/entrypoint_stats.sh"] \ No newline at end of file diff --git a/dff/utils/docker/superset_config_docker.py b/dff/utils/docker/superset_config_docker.py new file mode 100644 index 000000000..bea79993a --- /dev/null +++ b/dff/utils/docker/superset_config_docker.py @@ -0,0 +1,30 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# This is an example "local" configuration file. In order to set/override config +# options that ONLY apply to your local environment, simply copy/rename this file +# to docker/pythonpath/superset_config_docker.py +# It ends up being imported by docker/superset_config.py which is loaded by +# superset/config.py +# +import os + +SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{0}:{1}@psql:5432/{2}".format( + os.getenv("POSTGRES_USERNAME"), os.getenv("POSTGRES_PASSWORD"), os.getenv("POSTGRES_DB") +) +SQLALCHEMY_ECHO = True diff --git a/docker-compose.yml b/docker-compose.yml index 9c33c632a..b196ddc41 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,9 @@ services: context: ./dff/utils/docker dockerfile: dockerfile_stats image: ghcr.io/deeppavlov/superset_df_dashboard:latest + depends_on: + - 'psql' + - 'clickhouse' ports: - "8088:8088" clickhouse: @@ -57,6 +60,8 @@ services: container_name: otel-col restart: unless-stopped command: [ "--config=/etc/otelcol-config.yml", "--config=/etc/otelcol-config-extras.yml" ] + depends_on: + - 'clickhouse' volumes: - ./dff/utils/otel/otelcol-config.yml:/etc/otelcol-config.yml:ro - ./dff/utils/otel/otelcol-config-extras.yml:/etc/otelcol-config-extras.yml:ro From af92f36e4eea685cdfaeb8ab98273718868dff39 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 19 Oct 2023 17:52:16 +0300 Subject: [PATCH 33/46] move get_current_label to after_handler in sample_data_provider.py --- utils/stats/sample_data_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/stats/sample_data_provider.py b/utils/stats/sample_data_provider.py index 6ed22f494..d778c922a 100644 --- a/utils/stats/sample_data_provider.py +++ b/utils/stats/sample_data_provider.py @@ -63,11 +63,11 @@ async def get_confidence(ctx: Context, _, info: ExtraHandlerRuntimeInfo): Service( handler=ACTOR, before_handler=[ - default_extractors.get_current_label, default_extractors.get_timing_before, ], after_handler=[ default_extractors.get_timing_after, + default_extractors.get_current_label, default_extractors.get_last_request, default_extractors.get_last_response, ], From 9ae731ed72c95a64cf7ae9480acd62303e870fb6 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 20 Oct 2023 11:39:12 +0300 Subject: [PATCH 34/46] update sql with if statements --- .../datasets/dff_database/dff_node_stats.yaml | 2 +- dff/stats/cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index 2b87aee26..590116df9 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -14,7 +14,7 @@ sql: "\nWITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id' FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId and\ \ data_key = 'get_current_label'\n ORDER BY context_id, request_id\n) SELECT\ \ context_id,\n request_id,\n start_time,\n data_key,\n data,\n label,\n\ - \ neighbor(label, -1) as prev_label,\n neighbor(flow_label, -1) as prev_flow,\n\ + \ (request_id != '0' ? neighbor(label, -1) : '') as prev_label,\n (request_id != '0' ? neighbor(flow_label, -1) : '') as prev_flow,\n\ \ flow_label,\n node_label\nFROM main\n" params: null template_params: null diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 753e6af33..891948189 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -198,8 +198,8 @@ def make_zip_config(parsed_args: argparse.Namespace) -> Path: if OmegaConf.select(cli_conf, "db.driver") == "clickhousedb+connect": params = dict( table="${db.table}", - label_lag="neighbor(label, -1)", - flow_lag="neighbor(flow_label, -1)", + label_lag="(request_id != '0' ? neighbor(label, -1) : '')", + flow_lag="(request_id != '0' ? neighbor(flow_label, -1) : '')", texttype="String", lblfield="JSON_VALUE(${db.table}.Body, '$.label')", flowfield="JSON_VALUE(${db.table}.Body, '$.flow')", From cd0fc8e2ada91f9ab6de607670e93e69ac77a93c Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 20 Oct 2023 14:20:32 +0300 Subject: [PATCH 35/46] specify healthcheck for clickhouse and wait for healthcheck with otlp; make a variable for superset metadata db; adjust dockerfile to use configuration overrides --- .env_file | 3 ++- dff/utils/docker/dockerfile_stats | 3 ++- dff/utils/docker/superset_config_docker.py | 2 +- docker-compose.yml | 14 +++++++++++--- docs/source/user_guides/superset_guide.rst | 8 +++----- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/.env_file b/.env_file index 15b7a209a..1bb4cfae3 100644 --- a/.env_file +++ b/.env_file @@ -19,4 +19,5 @@ CLICKHOUSE_USER=username CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 CLICKHOUSE_PASSWORD=pass SUPERSET_USERNAME=superset -SUPERSET_PASSWORD=superset \ No newline at end of file +SUPERSET_PASSWORD=superset +SUPERSET_METADATA_DB=test \ No newline at end of file diff --git a/dff/utils/docker/dockerfile_stats b/dff/utils/docker/dockerfile_stats index e7f04022a..9c40071ea 100644 --- a/dff/utils/docker/dockerfile_stats +++ b/dff/utils/docker/dockerfile_stats @@ -2,6 +2,7 @@ FROM apache/superset:2.1.0rc1 USER root RUN cd /app && pip install .[clickhouse] COPY entrypoint_stats.sh /app/docker/ -COPY superset_config_docker.py /app/pythonpath/ +COPY --chown=superset superset_config_docker.py /app/pythonpath/ +ENV SUPERSET_CONFIG_PATH /app/pythonpath/superset_config_docker.py USER superset ENTRYPOINT ["/bin/bash","/app/docker/entrypoint_stats.sh"] \ No newline at end of file diff --git a/dff/utils/docker/superset_config_docker.py b/dff/utils/docker/superset_config_docker.py index bea79993a..58c9d8daa 100644 --- a/dff/utils/docker/superset_config_docker.py +++ b/dff/utils/docker/superset_config_docker.py @@ -25,6 +25,6 @@ import os SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{0}:{1}@psql:5432/{2}".format( - os.getenv("POSTGRES_USERNAME"), os.getenv("POSTGRES_PASSWORD"), os.getenv("POSTGRES_DB") + os.getenv("POSTGRES_USERNAME"), os.getenv("POSTGRES_PASSWORD"), os.getenv("SUPERSET_METADATA_DB") ) SQLALCHEMY_ECHO = True diff --git a/docker-compose.yml b/docker-compose.yml index dedee907f..0bf1800c2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,8 +52,10 @@ services: dockerfile: dockerfile_stats image: ghcr.io/deeppavlov/superset_df_dashboard:latest depends_on: - - 'psql' - - 'clickhouse' + psql: + condition: service_started + clickhouse: + condition: service_started profiles: - stats ports: @@ -70,6 +72,11 @@ services: - '9000:9000' volumes: - ch-data:/var/lib/clickhouse/ + healthcheck: + test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1 + interval: 2s + timeout: 2s + retries: 5 otelcol: image: otel/opentelemetry-collector-contrib:latest profiles: @@ -78,7 +85,8 @@ services: restart: unless-stopped command: [ "--config=/etc/otelcol-config.yml", "--config=/etc/otelcol-config-extras.yml" ] depends_on: - - 'clickhouse' + clickhouse: + condition: service_healthy volumes: - ./dff/utils/otel/otelcol-config.yml:/etc/otelcol-config.yml:ro - ./dff/utils/otel/otelcol-config-extras.yml:/etc/otelcol-config-extras.yml:ro diff --git a/docs/source/user_guides/superset_guide.rst b/docs/source/user_guides/superset_guide.rst index 5c4c3abb9..d3b4a29a1 100644 --- a/docs/source/user_guides/superset_guide.rst +++ b/docs/source/user_guides/superset_guide.rst @@ -174,12 +174,10 @@ a separate menu for data filters will also be available. If you need to use the from the `data` column, you will need to find the `custom_sql` option when adding the column and put in the extraction expression, as shown in the examples above. -**Persisting the chart configuration** +**Exporting the chart configuration** -If you define your own charts, it's important to save their configuration to the file system of your -host machine, so that no information is lost when the Superset container or the Docker process is restarted. - -The most convenient way to do that is to export the dashboard configuration as a whole. Navigate to the +The configuration of a Superset dashboard can be easily exported and then reused +in other Superset instances. This can be done using the GUI: navigate to the `Dashboards` section of the Superset application, locate your dashboard (named `DFF statistics` per default). Then press the `export` button on the right and save the zip file to any convenient location. From c53ab31f5f69bfc36114827ba22b381b98ed2150 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Fri, 20 Oct 2023 16:48:52 +0300 Subject: [PATCH 36/46] add dashboard-metadata docker image; adjust to run on port 5433 --- .env_file | 2 +- dff/utils/docker/superset_config_docker.py | 7 +++++-- docker-compose.yml | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.env_file b/.env_file index 1bb4cfae3..6295e4946 100644 --- a/.env_file +++ b/.env_file @@ -20,4 +20,4 @@ CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 CLICKHOUSE_PASSWORD=pass SUPERSET_USERNAME=superset SUPERSET_PASSWORD=superset -SUPERSET_METADATA_DB=test \ No newline at end of file +SUPERSET_METADATA_PORT=5433 \ No newline at end of file diff --git a/dff/utils/docker/superset_config_docker.py b/dff/utils/docker/superset_config_docker.py index 58c9d8daa..5b91059d5 100644 --- a/dff/utils/docker/superset_config_docker.py +++ b/dff/utils/docker/superset_config_docker.py @@ -24,7 +24,10 @@ # import os -SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{0}:{1}@psql:5432/{2}".format( - os.getenv("POSTGRES_USERNAME"), os.getenv("POSTGRES_PASSWORD"), os.getenv("SUPERSET_METADATA_DB") +SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{0}:{1}@dashboard-metadata:{2}/{3}".format( + os.getenv("POSTGRES_USERNAME"), + os.getenv("POSTGRES_PASSWORD"), + os.getenv("SUPERSET_METADATA_PORT"), + os.getenv("POSTGRES_DB"), ) SQLALCHEMY_ECHO = True diff --git a/docker-compose.yml b/docker-compose.yml index 0bf1800c2..20aca6f23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,6 @@ services: image: postgres:latest profiles: - context_storage - - stats restart: unless-stopped ports: - 5432:5432 @@ -52,7 +51,7 @@ services: dockerfile: dockerfile_stats image: ghcr.io/deeppavlov/superset_df_dashboard:latest depends_on: - psql: + dashboard-metadata: condition: service_started clickhouse: condition: service_started @@ -60,6 +59,17 @@ services: - stats ports: - "8088:8088" + dashboard-metadata: + env_file: [.env_file] + image: postgres:latest + profiles: + - stats + restart: unless-stopped + expose: + - "5433" + ports: + - 5433:5433 + command: -p 5433 clickhouse: env_file: [.env_file] image: clickhouse/clickhouse-server:latest From 32ce2ec8ef3ecfb2d506531fe96e21fdb4070792 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 24 Oct 2023 11:17:35 +0300 Subject: [PATCH 37/46] Update .github/workflows/update_dashboard.yml Apply suggestions from @RLKRo Co-authored-by: Roman Zlobin --- .github/workflows/update_dashboard.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/update_dashboard.yml b/.github/workflows/update_dashboard.yml index 3fc88299a..72042885f 100644 --- a/.github/workflows/update_dashboard.yml +++ b/.github/workflows/update_dashboard.yml @@ -5,8 +5,7 @@ on: branches: - 'master' paths: - - 'dff/utils/docker/dockerfile_stats' - - 'dff/utils/docker/entrypoint_stats.sh' + - 'dff/utils/docker/**' workflow_dispatch: concurrency: From 9bfaeac96efb61244d957143ff744ec4e830f027 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 24 Oct 2023 11:32:11 +0300 Subject: [PATCH 38/46] Update dff/stats/cli.py Apply suggestions to label_lag/flow_lag Co-authored-by: Roman Zlobin --- dff/stats/cli.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 891948189..38d1f69a5 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -198,8 +198,12 @@ def make_zip_config(parsed_args: argparse.Namespace) -> Path: if OmegaConf.select(cli_conf, "db.driver") == "clickhousedb+connect": params = dict( table="${db.table}", - label_lag="(request_id != '0' ? neighbor(label, -1) : '')", - flow_lag="(request_id != '0' ? neighbor(flow_label, -1) : '')", + label_lag="lagInFrame(label) OVER " + "(PARTITION BY context_id ORDER BY request_id ASC " + "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", + flow_lag="lagInFrame(flow_label) OVER " + "(PARTITION BY context_id ORDER BY request_id ASC " + "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", texttype="String", lblfield="JSON_VALUE(${db.table}.Body, '$.label')", flowfield="JSON_VALUE(${db.table}.Body, '$.flow')", From d73b8d4b50507fffd5ce17892c6842f9134354a6 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Tue, 24 Oct 2023 11:34:53 +0300 Subject: [PATCH 39/46] remove query statements from dashboard files; remove filter values from charts; update docker-compose healthcheck; apply formatting --- .../charts/Flow_visit_ratio_monitor_13.yaml | 2 +- .../charts/Node_visit_ratio_monitor_8.yaml | 2 +- .../datasets/dff_database/dff_node_stats.yaml | 12 +----------- .../datasets/dff_database/dff_stats.yaml | 11 +---------- dff/stats/cli.py | 8 ++++---- docker-compose.yml | 4 ++-- 6 files changed, 10 insertions(+), 29 deletions(-) diff --git a/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml b/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml index 633362e20..dfa036ee4 100644 --- a/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml +++ b/dff/config/superset_dashboard/charts/Flow_visit_ratio_monitor_13.yaml @@ -9,7 +9,7 @@ params: slice_id: 13 granularity_sqla: start_time time_grain_sqla: PT1M - time_range: 'DATEADD(DATETIME("now"), -1, day) : now' + time_range: No filter metrics: - aggregate: COUNT column: diff --git a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml index a733c5dc1..7f5852930 100644 --- a/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml +++ b/dff/config/superset_dashboard/charts/Node_visit_ratio_monitor_8.yaml @@ -9,7 +9,7 @@ params: slice_id: 2 granularity_sqla: start_time time_grain_sqla: PT1M - time_range: 'DATEADD(DATETIME("now"), -1, day) : now' + time_range: No filter metrics: - aggregate: COUNT column: diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index 590116df9..cc62e904c 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -5,17 +5,7 @@ default_endpoint: null offset: 0 cache_timeout: null schema: test -sql: "\nWITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id']\ - \ as context_id,\n otel_logs.LogAttributes['request_id'] as request_id,\n \ - \ toDateTime(otel_traces.Timestamp) as start_time,\n otel_traces.SpanName as\ - \ data_key,\n otel_logs.Body as data,\n JSON_VALUE(otel_logs.Body, '$.label')\ - \ as label,\n JSON_VALUE(otel_logs.Body, '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body,\ - \ '$.node') as node_label,\n otel_logs.TraceId as trace_id,\n otel_traces.TraceId\n\ - FROM otel_logs, otel_traces\n WHERE otel_logs.TraceId = otel_traces.TraceId and\ - \ data_key = 'get_current_label'\n ORDER BY context_id, request_id\n) SELECT\ - \ context_id,\n request_id,\n start_time,\n data_key,\n data,\n label,\n\ - \ (request_id != '0' ? neighbor(label, -1) : '') as prev_label,\n (request_id != '0' ? neighbor(flow_label, -1) : '') as prev_flow,\n\ - \ flow_label,\n node_label\nFROM main\n" +sql: null params: null template_params: null filter_select_enabled: false diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml index 142a2ccc0..f8044ae98 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml @@ -5,16 +5,7 @@ default_endpoint: null offset: 0 cache_timeout: null schema: test -sql: "WITH main AS (\n SELECT DISTINCT otel_logs.LogAttributes['context_id'] as\ - \ context_id,\n otel_logs.LogAttributes['request_id'] as request_id,\n toDateTime(otel_traces.Timestamp)\ - \ as start_time,\n otel_traces.SpanName as data_key,\n otel_logs.Body as data,\n\ - \ JSON_VALUE(otel_logs.Body, '$.label') as label,\n JSON_VALUE(otel_logs.Body,\ - \ '$.flow') as flow_label,\n JSON_VALUE(otel_logs.Body, '$.node') as node_label,\n\ - \ otel_logs.TraceId as trace_id,\n otel_traces.TraceId\nFROM otel_logs, otel_traces\n\ - \ WHERE otel_logs.TraceId = otel_traces.TraceId\n ORDER BY data_key, context_id,\ - \ request_id\n) SELECT context_id,\n request_id,\n start_time,\n data_key,\n\ - \ data,\n label,\n neighbor(label, -1) as prev_label,\n neighbor(flow_label,\ - \ -1) as prev_flow,\n flow_label,\n node_label\nFROM main" +sql: null params: null template_params: null filter_select_enabled: false diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 38d1f69a5..1d3245cd1 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -199,11 +199,11 @@ def make_zip_config(parsed_args: argparse.Namespace) -> Path: params = dict( table="${db.table}", label_lag="lagInFrame(label) OVER " - "(PARTITION BY context_id ORDER BY request_id ASC " - "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", + "(PARTITION BY context_id ORDER BY request_id ASC " + "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", flow_lag="lagInFrame(flow_label) OVER " - "(PARTITION BY context_id ORDER BY request_id ASC " - "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", + "(PARTITION BY context_id ORDER BY request_id ASC " + "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)", texttype="String", lblfield="JSON_VALUE(${db.table}.Body, '$.label')", flowfield="JSON_VALUE(${db.table}.Body, '$.flow')", diff --git a/docker-compose.yml b/docker-compose.yml index 20aca6f23..adf18f024 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -84,8 +84,8 @@ services: - ch-data:/var/lib/clickhouse/ healthcheck: test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1 - interval: 2s - timeout: 2s + interval: 5s + timeout: 4s retries: 5 otelcol: image: otel/opentelemetry-collector-contrib:latest From e8e725d6bf8bdb4ee10dc3ada01a0c16ab78c9ef Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Wed, 25 Oct 2023 12:13:59 +0300 Subject: [PATCH 40/46] wait for pg database; sleep to avoid process conflict --- dff/utils/docker/entrypoint_stats.sh | 1 + dff/utils/docker/superset_config_docker.py | 1 - docker-compose.yml | 7 ++++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dff/utils/docker/entrypoint_stats.sh b/dff/utils/docker/entrypoint_stats.sh index 663a39b75..cac946f7d 100644 --- a/dff/utils/docker/entrypoint_stats.sh +++ b/dff/utils/docker/entrypoint_stats.sh @@ -2,6 +2,7 @@ export SERVER_THREADS_AMOUNT=8 set -m nohup /bin/bash /usr/bin/run-server.sh & +sleep 5 superset fab create-admin --firstname superset --lastname admin --username $SUPERSET_USERNAME --email admin@admin.com --password $SUPERSET_PASSWORD superset db upgrade superset init diff --git a/dff/utils/docker/superset_config_docker.py b/dff/utils/docker/superset_config_docker.py index 5b91059d5..ca138927f 100644 --- a/dff/utils/docker/superset_config_docker.py +++ b/dff/utils/docker/superset_config_docker.py @@ -30,4 +30,3 @@ os.getenv("SUPERSET_METADATA_PORT"), os.getenv("POSTGRES_DB"), ) -SQLALCHEMY_ECHO = True diff --git a/docker-compose.yml b/docker-compose.yml index adf18f024..a3dffc883 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,7 +52,7 @@ services: image: ghcr.io/deeppavlov/superset_df_dashboard:latest depends_on: dashboard-metadata: - condition: service_started + condition: service_healthy clickhouse: condition: service_started profiles: @@ -70,6 +70,11 @@ services: ports: - 5433:5433 command: -p 5433 + healthcheck: + test: pg_isready -p 5433 + interval: 4s + timeout: 3s + retries: 3 clickhouse: env_file: [.env_file] image: clickhouse/clickhouse-server:latest From ec7cf06f5434a932154958d7a7772791024b4e20 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 26 Oct 2023 12:00:25 +0300 Subject: [PATCH 41/46] Apply suggestions by @RLKRo Apply suggestions by @RLKRo Co-authored-by: Roman Zlobin --- dff/stats/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 1d3245cd1..f19d8aa41 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -87,7 +87,7 @@ DFF_STATS_STATEMENT = """ WITH main AS ( SELECT DISTINCT {table}.LogAttributes['context_id'] as context_id, - {table}.LogAttributes['request_id'] as request_id, + toUInt64OrNull({table}.LogAttributes['request_id']) as request_id, toDateTime(otel_traces.Timestamp) as start_time, otel_traces.SpanName as data_key, {table}.Body as data, @@ -118,7 +118,7 @@ ) SELECT DISTINCT LogAttributes['context_id'] AS context_id, LogAttributes['request_id'] AS request_id, -otel_traces.Timestamp AS start_time, +toDateTime(otel_traces.Timestamp) AS start_time, {lblfield} AS label, {flowfield} AS flow_label, {nodefield} AS node_label From fb3cf72958804fdf499ed5bfba01d87a694f7b07 Mon Sep 17 00:00:00 2001 From: ruthenian8 Date: Thu, 26 Oct 2023 15:02:08 +0300 Subject: [PATCH 42/46] Update config files; Update sql expressions in CLI; update healthcheck expression; create volume for dashboard metadata --- .../dashboards/DFF_statistics_dashboard_1.yaml | 4 ++-- .../datasets/dff_database/dff_final_nodes.yaml | 2 +- .../datasets/dff_database/dff_node_stats.yaml | 2 +- .../superset_dashboard/datasets/dff_database/dff_stats.yaml | 2 +- dff/stats/cli.py | 2 +- docker-compose.yml | 6 +++++- makefile | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index 90b002427..b78e29bb9 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -1148,8 +1148,7 @@ metadata: scope: rootPath: - TAB-6zE8noCIsx - excluded: - - 15 + excluded: [] type: NATIVE_FILTER description: '' chartsInScope: @@ -1164,6 +1163,7 @@ metadata: - 12 - 13 - 14 + - 15 tabsInScope: - TAB-6zE8noCIsx - TAB-Gw0Ffh1lG diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml index a07fdd800..a618904af 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml @@ -33,7 +33,7 @@ columns: verbose_name: null is_dttm: true is_active: true - type: DateTime64(9) + type: DateTime advanced_data_type: null groupby: true filterable: true diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml index cc62e904c..4e2cc5792 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_node_stats.yaml @@ -110,7 +110,7 @@ columns: verbose_name: null is_dttm: false is_active: true - type: String + type: Nullable(UInt64) advanced_data_type: null groupby: true filterable: true diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml index f8044ae98..6f1efe683 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_stats.yaml @@ -98,7 +98,7 @@ columns: verbose_name: null is_dttm: false is_active: true - type: String + type: Nullable(UInt64) advanced_data_type: null groupby: true filterable: true diff --git a/dff/stats/cli.py b/dff/stats/cli.py index f19d8aa41..4164788c6 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -61,7 +61,7 @@ DFF_NODE_STATS_STATEMENT = """ WITH main AS ( SELECT DISTINCT {table}.LogAttributes['context_id'] as context_id, - {table}.LogAttributes['request_id'] as request_id, + toUInt64OrNull({table}.LogAttributes['request_id']) as request_id, toDateTime(otel_traces.Timestamp) as start_time, otel_traces.SpanName as data_key, {table}.Body as data, diff --git a/docker-compose.yml b/docker-compose.yml index a3dffc883..3c88bc854 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,10 +71,12 @@ services: - 5433:5433 command: -p 5433 healthcheck: - test: pg_isready -p 5433 + test: pg_isready -p 5433 --username=$${POSTGRES_USERNAME} interval: 4s timeout: 3s retries: 3 + volumes: + - dashboard-data:/var/lib/postgresql/data clickhouse: env_file: [.env_file] image: clickhouse/clickhouse-server:latest @@ -111,3 +113,5 @@ services: volumes: ch-data: name: "ch-data" + dashboard-data: + name: "dashboard-data" diff --git a/makefile b/makefile index e182bfcdf..cd4a36789 100644 --- a/makefile +++ b/makefile @@ -50,7 +50,7 @@ lint: venv .PHONY: lint docker_up: - docker-compose --profile context_storage --profile stats up -d + docker-compose --profile context_storage --profile stats up -d --build .PHONY: docker_up wait_db: docker_up From fa5d55029940e7bd92e4ed9ae8cb10fd1f24e091 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 26 Oct 2023 17:25:24 +0300 Subject: [PATCH 43/46] convert request_id to int in final_nodes --- .../datasets/dff_database/dff_final_nodes.yaml | 2 +- dff/stats/cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml index a618904af..62cf42676 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml @@ -81,7 +81,7 @@ columns: verbose_name: null is_dttm: false is_active: true - type: String + type: Nullable(UInt64) advanced_data_type: null groupby: true filterable: true diff --git a/dff/stats/cli.py b/dff/stats/cli.py index 4164788c6..2b881b00d 100644 --- a/dff/stats/cli.py +++ b/dff/stats/cli.py @@ -113,11 +113,11 @@ DFF_FINAL_NODES_STATEMENT = """ WITH main AS ( SELECT LogAttributes['context_id'] AS context_id, - max(LogAttributes['request_id']) AS max_history + max(toUInt64OrNull(LogAttributes['request_id'])) AS max_history FROM {table}\nGROUP BY context_id ) SELECT DISTINCT LogAttributes['context_id'] AS context_id, -LogAttributes['request_id'] AS request_id, +toUInt64OrNull({table}.LogAttributes['request_id']) AS request_id, toDateTime(otel_traces.Timestamp) AS start_time, {lblfield} AS label, {flowfield} AS flow_label, From 3fad9d65ddbf13888090c0baa06971c3c205f7a0 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 26 Oct 2023 17:25:52 +0300 Subject: [PATCH 44/46] remove sql in final_nodes --- .../datasets/dff_database/dff_final_nodes.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml index 62cf42676..4a8628298 100644 --- a/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml +++ b/dff/config/superset_dashboard/datasets/dff_database/dff_final_nodes.yaml @@ -5,14 +5,7 @@ default_endpoint: null offset: 0 cache_timeout: null schema: test -sql: "\nWITH main AS (\n SELECT LogAttributes['context_id'] AS context_id,\n \ - \ max(LogAttributes['request_id']) AS max_history\n FROM otel_logs\nGROUP BY\ - \ context_id\n)\nSELECT DISTINCT LogAttributes['context_id'] AS context_id,\nLogAttributes['request_id']\ - \ AS request_id,\notel_logs.Timestamp AS start_time,\nJSON_VALUE(otel_logs.Body,\ - \ '$.label') AS label,\nJSON_VALUE(otel_logs.Body, '$.flow') AS flow_label,\nJSON_VALUE(otel_logs.Body,\ - \ '$.node') AS node_label\nFROM otel_logs\nINNER JOIN main\nON context_id = main.context_id\n\ - AND request_id = main.max_history\nINNER JOIN otel_traces\nON otel_logs.TraceId\ - \ = otel_traces.TraceId\nWHERE otel_traces.SpanName = 'get_current_label'\n" +sql: null params: null template_params: null filter_select_enabled: false From 464a2bdafe1c41b4e07b94c3ca4f4062d709913e Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 26 Oct 2023 17:26:29 +0300 Subject: [PATCH 45/46] update history filter to numerical range type & change datasource to node_stats --- .../dashboards/DFF_statistics_dashboard_1.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml index b78e29bb9..ce8e32496 100644 --- a/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml +++ b/dff/config/superset_dashboard/dashboards/DFF_statistics_dashboard_1.yaml @@ -1171,16 +1171,12 @@ metadata: - id: NATIVE_FILTER-Q_v9J5gqV controlValues: enableEmptyFilter: false - defaultToFirstItem: false - multiSelect: true - searchAllOptions: false - inverseSelection: false name: History - filterType: filter_select + filterType: filter_range targets: - column: name: request_id - datasetUuid: d7f6546e-1e3a-479d-8531-05b5e73e5c05 + datasetUuid: fda98ab8-f550-45f1-9ded-0113f3e67260 defaultDataMask: extraFormData: {} filterState: {} From c329025a13871fdce1900ac06335e4423489bf45 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 26 Oct 2023 18:33:54 +0300 Subject: [PATCH 46/46] remove utils include from manifest --- MANIFEST.in | 1 - 1 file changed, 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 11a3392f8..2bf8bfe27 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,7 +3,6 @@ include LICENSE include README.md graft dff/config/superset_dashboard include dff/context_storages/protocols.json -recursive-include utils * exclude makefile