def plot_function_execution_time(data, plot_dir): cgroups = create_requestgroups(data) fn_calls = group_by(cgroups, lambda c: c.function) function_durations = {} for function, calls in fn_calls.items(): if function not in ("artillery", None): function_durations[function] = [ c.start_time for c in calls if c.start_time is not None ] fig = plot_kdeplot(function_durations, ylabel="Invocation Count", title="KDE of function invocations", log_scaling=True) plot_path = str(plot_dir / "function_invocations.png") print(f"Plotting to {plot_path}") fig.savefig(plot_path)
def plot_function_coldstarts(data, plot_dir): cld_groups = [d for d in data if isinstance(d, ColdstartLog)] fn_calls = group_by(cld_groups, lambda c: c.function) function_coldstarts = {} for function, calls in fn_calls.items(): function_coldstarts[function] = [ c.timestamp for c in calls if c.timestamp is not None ] fig = plot_kdeplot(function_coldstarts, ylabel="Coldstart Count", title="KDE of function coldstarts", log_scaling=True) plot_path = str(plot_dir / "function_coldstarts.png") print(f"Plotting to {plot_path}") fig.savefig(plot_path)
def plot_function_execution_time(data, plot_dir): cgroups = create_requestgroups(data) fn_calls = group_by(cgroups, lambda c: c.function) function_durations = {} for function, calls in fn_calls.items(): if function not in ("artillery", None): function_durations[function] = [ timedelta_to_ms(c.duration) for c in calls if c.duration is not None ] fig = plot_boxplot( function_durations, ylabel="Execution Time (ms)", title="Comparison of total execution time in current deployment.", log_scaling=True) plot_path = str(plot_dir / "boxplot_function_execution_time.png") print(f"Plotting to {plot_path}") fig.savefig(plot_path)
def apply_agraph_style(A, graph, filters, style): cluster_style = style["cluster_style"] node_vals = nx.get_node_attributes(graph, "platform") val_nodes = defaultdict(list) for node, value in node_vals.items(): if value not in ("artillery", "__caller__"): val_nodes[value].append(node) # create subgraphs for value, nodes in val_nodes.items(): # skip empty providers if not nodes: continue subgraph_name = f"cluster_{value}" platgroup = A.add_subgraph(nodes, name=subgraph_name, label=value, **cluster_style) # set border color for included nodes for node in nodes: A.get_node(node).attr["color"] = cluster_style.get("fillcolor", "") # create nested subgraph on function if call graph if filters["context_id"]: for name, fnodes in group_by( nodes, lambda e: get_node_function(graph, e)).items(): platgroup.add_subgraph(fnodes, name=f"cluster_{name}", label=name, **cluster_style) A.layout(style["layout"]) return A