def test_ts_chart_with_publish_label_options(): opts = PublishLabelOptions('somelabel', 0, PaletteColor.mountain_green, PlotType.area_chart, 'foo') chart = TimeSeriesChart().with_publish_label_options(opts) assert chart.chart_options['publishLabelOptions'] == [opts.to_dict()]
def test_ts_chart_with_prefix(prefix): chart = TimeSeriesChart().with_unit_prefix(prefix) assert chart.chart_options['unitPrefix'] == prefix.value
def test_dashboard_create(): chart1 = TimeSeriesChart() chart1.with_name('chart1') chart1.with_program("data('requests.min').publish()") chart1.with_default_plot_type(PlotType.area_chart) chart2 = TimeSeriesChart() chart2.with_name('chart2') chart2.with_program("data('requests.min').publish()") chart2.with_default_plot_type(PlotType.line_chart) dashboard_name = 'removeme111' dashboard = Dashboard() dashboard.with_charts(chart1, chart2) dashboard.with_name(dashboard_name) f = StringIO() with stdout_redirected(f): dashboard.create(dry_run=True) response = f.getvalue() result_string = response[response.find('{'):]\ .replace('\'', '\"')\ .replace('("', '(\\"')\ .replace('")', '\\")') result = json.loads(result_string) assert 'charts' in result assert 'name' in result assert len(result['charts']) == 2 assert result['name'] == dashboard_name assert result['charts'][0]['options']['defaultPlotType'] \ == PlotType.area_chart.value assert result['charts'][1]['options']['defaultPlotType'] \ == PlotType.line_chart.value
def create_kinesis_charts(stream_name, description): """ Create Kinesis charts Left chart shows incoming records and outgoing records. Right chart shows errors, throttles, and iterator age. """ charts = [] sum_filter = And(Filter("StreamName", stream_name), Filter("namespace", "AWS/Kinesis"), Filter("stat", "sum")) charts.append( TimeSeriesChart() \ .with_name("Kinesis Stream " + stream_name) \ .with_description(description) .with_default_plot_type(PlotType.column_chart) \ .with_chart_legend_options("sf_metric", show_legend=True) .with_publish_label_options( PublishLabelOptions( label='IncomingRecords', palette_index=PaletteColor.green ), PublishLabelOptions( label='GetRecords.Records', palette_index=PaletteColor.light_green ) ).with_axes([AxisOption(label="Count")]) .with_program( Program( Plot( assigned_name="A", signal_name="IncomingRecords", filter=sum_filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "StreamName"])], label="IncomingRecords"), Plot( assigned_name="B", signal_name="GetRecords.Records", filter=sum_filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "StreamName"])], label="GetRecords.Records") ) ) ) charts.append( TimeSeriesChart() \ .with_name("Kinesis Stream " + stream_name) \ .with_description(description) .with_default_plot_type(PlotType.column_chart) \ .with_chart_legend_options("sf_metric", show_legend=True) .with_publish_label_options( PublishLabelOptions( label='ReadThroughputExceeded', palette_index=PaletteColor.rust, y_axis=0 ), PublishLabelOptions( label='WriteThroughputExceeded', palette_index=PaletteColor.tangerine, y_axis=0 ), PublishLabelOptions( label='GetRecords.IteratorAge', palette_index=PaletteColor.sunflower, value_unit='Millisecond', plot_type=PlotType.area_chart, y_axis=1 )).with_axes([AxisOption(label="Count"), AxisOption(label="Age")]) .with_program( Program( Plot( assigned_name="A", signal_name="ReadProvisionedThroughputExceeded", filter=sum_filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "StreamName"])], label="ReadThroughputExceeded"), Plot( assigned_name="B", signal_name="WriteProvisionedThroughputExceeded", filter=sum_filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "StreamName"])], label="WriteThroughputExceeded"), Plot( assigned_name="C", signal_name="GetRecords.IteratorAgeMilliseconds", filter=And( Filter("StreamName", stream_name), Filter("namespace", "AWS/Kinesis"), Filter("stat", "upper") ), rollup=RollupType.max, # max rollup is used here so you can still see spikes over longer windows fx=[Sum(by=["aws_account_id", "StreamName"])], label="GetRecords.IteratorAge") ) ) ) return charts
def test_ts_chart_with_axis_precision(): chart = TimeSeriesChart().with_axis_precision(1) assert chart.chart_options['axisPrecision'] == 1
def test_ts_chart_with_time_config_relative(): opts = {'type': 'relative', 'range': 1000} chart = TimeSeriesChart().with_time_config_relative(1000) assert chart.chart_options['time'] == opts
def test_ts_chart_with_field_options(): field_opt = FieldOption('foo') opt = {'fields': [field_opt.to_dict()]} chart = TimeSeriesChart().with_legend_options([field_opt]) assert chart.chart_options['legendOptions'] == opt
def test_ts_chart_show_event_lines(): chart = TimeSeriesChart().show_event_lines(True) assert chart.chart_options['showEventLines'] == 'true'
def test_ts_chart_with_modified_linechart_options(): opts = {'showDataMarkers': True} chart = TimeSeriesChart()\ .with_default_plot_type(PlotType.area_chart)\ .with_area_chart_options(show_data_markers=True) assert chart.chart_options['areaChartOptions'] == opts
def test_ts_chart_with_wrong_chart_options(): with pytest.raises(ValueError): TimeSeriesChart()\ .with_default_plot_type(PlotType.area_chart)\ .with_line_chart_options()
def test_ts_chart_with_areachart_options(): opts = {'showDataMarkers': False} chart = TimeSeriesChart()\ .with_default_plot_type(PlotType.area_chart)\ .with_area_chart_options() assert chart.chart_options['areaChartOptions'] == opts
def test_ts_chart_with_time_config_absolute(): opts = {'type': 'absolute', 'start': 1, 'end': 2} chart = TimeSeriesChart().with_time_config_absolute(1, 2) assert chart.chart_options['time'] == opts
#!/usr/bin/env python """Examples for the `signal_analog.eventoverlays` module.""" from signal_analog.flow import Data from signal_analog.charts import TimeSeriesChart from signal_analog.dashboards import Dashboard from signal_analog.eventoverlays import EventSignals, EventOverlays, SelectedEventOverlays """ Example 1: Creating a new Dashboard with event overlay markers set to show by default This creates a new dashboard which will show event markers marked with "deploy" by default. """ program = Data('cpu.utilization').publish() chart = TimeSeriesChart().with_name('TacoChart').with_program(program).show_event_lines(True) events = EventSignals().with_event_search_text("deploy")\ .with_event_type("eventTimeSeries") eventoverlay = EventOverlays().with_event_signals(events)\ .with_event_color_index(1)\ .with_event_line(True) selectedeventoverlay = SelectedEventOverlays()\ .with_event_signals(events) dashboard_with_event_overlays = Dashboard().with_name('Dashboard Named Snek')\ .with_charts(chart)\ .with_event_overlay(eventoverlay)\ .with_selected_event_overlay(selectedeventoverlay)
def test_ts_chart_with_color_by(color_by): chart = TimeSeriesChart().with_color_by(color_by) assert chart.chart_options['colorBy'] == color_by.value
def test_ts_chart_with_field_options_disabled(): field_opt = FieldOption('bar', enabled=False) opt = {'fields': [field_opt.to_dict()]} chart = TimeSeriesChart().with_legend_options([field_opt]) assert chart.chart_options['legendOptions'] == opt
def test_ts_chart_with_default_plot_type(plot_type): chart = TimeSeriesChart().with_default_plot_type(plot_type) assert chart.chart_options['defaultPlotType'] == plot_type.value
def test_ts_chart_with_publish_label_options(): """'Legacy' behavior, verified still working.""" opts = PublishLabelOptions('somelabel', 0, PaletteColor.mountain_green, PlotType.area_chart, 'foo') chart = TimeSeriesChart().with_publish_label_options(opts) assert chart.chart_options['publishLabelOptions'] == [opts.to_dict()]
def test_ts_chart_stack_chart(): chart = TimeSeriesChart().stack_chart(False) assert chart.chart_options['stacked'] is False
def test_ts_chart_with_legend_options(): opts = {'showLegend': True, 'dimensionInLegend': 'foo'} chart = TimeSeriesChart()\ .with_chart_legend_options('foo', show_legend=True) assert chart.chart_options['onChartLegendOptions'] == opts
def test_ts_chart_with_program_opts(): opts = {'minimumResolution': 1, 'maxDelay': 2, 'disableSampling': False} chart = TimeSeriesChart().with_program_options(1, 2) assert chart.chart_options['programOptions'] == opts
def test_ts_chart_include_zero_options(): chart = TimeSeriesChart().with_include_zero(True) assert chart.chart_options['includeZero'] is True
def mk_chart(name): program = Data('cpu.utilization').publish() return TimeSeriesChart(session=global_session)\ .with_name(name)\ .with_program(program)
def test_ts_chart_init(): assert TimeSeriesChart().chart_options['type'] == 'TimeSeriesChart'
from signal_analog.flow import Data, Filter, Program, Plot, RollupType, Sum from signal_analog.combinators import And """ Example 1: single-use chart This is useful when you just want to create a chart and aren't worried about re-usability. """ # Look at the mean of the cpu.user metric for my-app in the prod environment app_filter = And(Filter('app', 'my-app'), Filter('env', 'prod')) program = Program(Data('cpu.user', filter=app_filter).mean().publish('A')) chart = TimeSeriesChart()\ .with_name('CPU Used %')\ .with_description('% CPU used by user')\ .stack_chart(True)\ .with_default_plot_type(PlotType.area_chart)\ .with_program(program) """ Example 2: make a re-usable chart (or template) This is useful when you want your chart to be broadly applicable/used by others """ class UserCpuUsedPercentChart(TimeSeriesChart): def __init__(self, app, env='prod'): super(UserCpuUsedPercentChart, self).__init__() self.with_name('CPU Used % from template class') self.with_description( '% CPU used by type (user, system, i/o, stolen, etc)')
def test_ts_chart_without_enums(bad_input): with pytest.raises(ValueError): TimeSeriesChart().with_unit_prefix(bad_input) TimeSeriesChart().with_color_by(bad_input) TimeSeriesChart().with_default_plot_type(bad_input)
def create_sqs_charts(queue_name, description): """ Create SQS charts Left chart shows messages sent/deleted and number visible. Right chart shows deadletter queue and age of oldest message. """ charts = [] filter = And(Filter("QueueName", queue_name), Filter("namespace", "AWS/SQS"), Filter("stat", "sum")) charts.append( TimeSeriesChart() \ .with_name("SQS " + queue_name) \ .with_description(description) .with_default_plot_type(PlotType.column_chart) \ .with_chart_legend_options("sf_metric", show_legend=True) .with_publish_label_options( PublishLabelOptions( label='NumberOfMessagesSent', palette_index=PaletteColor.green ), PublishLabelOptions( label='NumberOfMessagesDeleted', palette_index=PaletteColor.light_green ), PublishLabelOptions( label='ApproximateNumberOfMessagesVisible', palette_index=PaletteColor.sky_blue, plot_type=PlotType.line_chart ) ).with_axes([AxisOption(label="Count", min=0)]) .with_program( Program( Plot( assigned_name="A", signal_name="NumberOfMessagesSent", filter=filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "QueueName"])], label="NumberOfMessagesSent"), Plot( assigned_name="B", signal_name="NumberOfMessagesDeleted", filter=filter, rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "QueueName"])], label="NumberOfMessagesDeleted"), Plot( assigned_name="C", signal_name="ApproximateNumberOfMessagesVisible", filter=filter, rollup=RollupType.max, fx=[Max(by=["aws_account_id", "QueueName"])], label="ApproximateNumberOfMessagesVisible") ) ) ) charts.append( TimeSeriesChart() \ .with_name("SQS " + queue_name) \ .with_description(description) .with_default_plot_type(PlotType.column_chart) \ .with_chart_legend_options("sf_metric", show_legend=True) .with_publish_label_options( PublishLabelOptions( label='DeadLetterMessages', palette_index=PaletteColor.mulberry, y_axis=0 ), PublishLabelOptions( label='ApproximateAgeOfOldestMessage', palette_index=PaletteColor.sunflower, value_unit='Second', plot_type=PlotType.area_chart, y_axis=1 ) ).with_axes([AxisOption(label="Count", min=0), AxisOption(label="Age", min=0)]) .with_program( Program( Plot( assigned_name="A", signal_name="ApproximateNumberOfMessagesVisible", filter=And( # assumes naming convention for DL queues Filter("QueueName", queue_name + "-deadletter", queue_name + "-dlq"), Filter("namespace", "AWS/SQS"), Filter("stat", "upper") ), rollup=RollupType.max, fx=[Sum(by=["aws_account_id", "QueueName"])], label="DeadLetterMessages"), Plot( assigned_name="B", signal_name="ApproximateAgeOfOldestMessage", filter=And( Filter("QueueName", queue_name), Filter("namespace", "AWS/SQS"), Filter("stat", "upper") ), rollup=RollupType.max, # max rollup is used here so you can still see spikes over longer windows fx=[Max(by=["aws_account_id", "QueueName"])], label="ApproximateAgeOfOldestMessage") ) ) ) return charts
from signal_analog.dashboards import Dashboard, DashboardGroup from signal_analog.combinators import And """ Example 1: Creating a new Dashboard Group This creates a new dashboard group """ dashboard_group = DashboardGroup().with_name('Dashboard Group Name') """ Example 2: Creating a new Dashboard Group with Dashboards """ filters = And(Filter('app', 'my-app'), Filter('env', 'test')) program = Data('cpu.utilization', filter=filters).publish() chart = TimeSeriesChart().with_name('Chart_Name').with_program(program) program1 = Data('network.utilization', filter=filters).publish() chart1 = TimeSeriesChart().with_name('Chart_Name').with_program(program) program2 = Data('api_errors', filter=filters).publish() chart2 = TimeSeriesChart().with_name('Chart_Name').with_program(program) dashboard1 = Dashboard().with_name('Dashboard1').with_charts(chart) dashboard2 = Dashboard().with_name('Dashboard2').with_charts(chart, chart1) dashboard3 = Dashboard().with_name('Dashboard3')\ .with_charts(chart, chart1, chart2) dashboard_group_with_dashboards = DashboardGroup() \ .with_name('Dashboard Group Name') \ .with_dashboards(dashboard1, dashboard2, dashboard3)