def test_ts_chart_with_axes(): axis_of_evil = AxisOption(1, 2, 'evil', 1, 2) opts = [axis_of_evil.to_dict()] chart = TimeSeriesChart().with_axes([axis_of_evil]) assert chart.chart_options['axes'] == opts
def test_chart_with_empties(value): with pytest.raises(ValueError): Chart().with_name(value) Chart().with_description(value) Chart().with_program() AxisOption(value, value, value, value, value) FieldOption(value, False) PublishLabelOptions(value, value, value, value, value)
def test_axis_option_max_greater_than_min(): with pytest.raises(ValueError): AxisOption(1, 0, 'evil', 1, 2)
def create_dynamodb_charts(table_name, description): """ Create charts for DynamoDB Table. Left chart shows read/write capacity consumed, plus latency. Right chart shows Errors and Throttling. """ charts = [] charts.append( TimeSeriesChart() \ .with_name("Dynamo Table " + table_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='ConsumedReadCapacity', palette_index=PaletteColor.green ), PublishLabelOptions( label='ConsumedWriteCapacity', palette_index=PaletteColor.light_green ), PublishLabelOptions( label='Latency', palette_index=PaletteColor.gray, plot_type=PlotType.line_chart, value_unit='Millisecond', y_axis=1 ) ).with_axes([AxisOption(label="Units", min=0), AxisOption(label="Latency", min=0)]) .with_program( Program( Plot( assigned_name="A", signal_name="ConsumedReadCapacityUnits", filter=And( Filter("TableName", table_name), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="ConsumedReadCapacity" ), Plot( assigned_name="B", signal_name="ConsumedWriteCapacityUnits", filter=And( Filter("TableName", table_name), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="ConsumedWriteCapacity" ), Plot( assigned_name="C", signal_name="SuccessfulRequestLatency", filter=And( Filter("TableName", table_name), Filter("stat", "mean") ), rollup=RollupType.max, fx=[Mean(by=["TableName", "aws_account_id"])], label="Latency" ) ) ) ) charts.append( TimeSeriesChart() \ .with_name("Dynamo Table " + table_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='ThrottledRequests', palette_index=PaletteColor.rust ), PublishLabelOptions( label='ReadThrottle', palette_index=PaletteColor.tangerine ), PublishLabelOptions( label='WriteThrottle', palette_index=PaletteColor.sunflower ), PublishLabelOptions( label='SystemErrors', palette_index=PaletteColor.rose, y_axis=1 ) ).with_program( Program( Plot( assigned_name="A", signal_name="ThrottledRequests", filter=And( Filter("TableName", table_name), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="ThrottledRequests" ), Plot( assigned_name="B", signal_name="ReadThrottleEvents", filter=And( Filter("TableName", table_name), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="ReadThrottle" ), Plot( assigned_name="C", signal_name="WriteThrottleEvents", filter=And( Filter("TableName", table_name), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="WriteThrottle" ), Plot( assigned_name="D", signal_name="SystemErrors", filter=And( Filter("TableName", table_name), Filter("stat", "sum"), Not(Filter("Operation", "GetRecords")) # GetRecords is a Dynamo Stream operation ), rollup=RollupType.sum, fx=[Sum(by=["TableName", "aws_account_id"])], label="SystemErrors") ) ) ) return charts
def create_lambda_charts(function_name, description): """ Create Lambda charts Left chart shows activity and latency. Right chart shows errors, throttles, and iterator age. """ charts = [] charts.append( TimeSeriesChart() \ .with_name("Lambda " + function_name + " Invocations") \ .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='Invocations', palette_index=PaletteColor.green ), PublishLabelOptions( label='Duration', palette_index=PaletteColor.gray, y_axis=1, plot_type=PlotType.line_chart, value_unit='Millisecond' ) ) .with_axes([AxisOption(label="Count", min=0), AxisOption(label="Latency", min=0)]) .with_program( Program( Plot( assigned_name="A", signal_name="Invocations", filter=And( Filter("FunctionName", function_name), Filter("namespace", "AWS/Lambda"), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "FunctionName"])], label="Invocations"), Plot( assigned_name="B", signal_name="Duration", filter=And( Filter("FunctionName", function_name), Filter("namespace", "AWS/Lambda"), Filter("stat", "mean") ), rollup=RollupType.max, # max rollup is used here so you can still see spikes over longer windows fx=[Sum(by=["aws_account_id", "FunctionName"])], label="Duration") ) ) ) charts.append( TimeSeriesChart() \ .with_name("Lambda " + function_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='Errors', palette_index=PaletteColor.rust ), PublishLabelOptions( label='Throttles', palette_index=PaletteColor.sunflower ), PublishLabelOptions( label='IteratorAge', value_unit='Millisecond', plot_type=PlotType.area_chart, palette_index=PaletteColor.slate_blue, y_axis=1 ) ).with_axes([AxisOption(label="Count", min=0), AxisOption(label="Age", min=0, max=(1000 * 60 * 60 * 36))]) .with_program( Program( Plot( assigned_name="B", signal_name="Errors", filter=And( Filter("FunctionName", function_name), Filter("namespace", "AWS/Lambda"), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "FunctionName"])], label="Errors"), Plot( assigned_name="C", signal_name="Throttles", filter=And( Filter("FunctionName", function_name), Filter("namespace", "AWS/Lambda"), Filter("stat", "sum") ), rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "FunctionName"])], label="Throttles"), Plot( assigned_name="D", signal_name="IteratorAge", filter=And( Filter("FunctionName", function_name), Filter("Resource", function_name), Filter("namespace", "AWS/Lambda"), Filter('stat', 'upper') ), rollup=RollupType.max, # max rollup is used here so you can still see spikes over longer windows # Max here is just to get rid of bad extra metric in Sfx fx=[Max(by=["aws_account_id", "FunctionName"])], label="IteratorAge") ) ) ) return charts
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
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
.with_chart_legend_options("sf_metric", show_legend=True) \ .with_publish_label_options( PublishLabelOptions( label='Invocations', palette_index=PaletteColor.green ), PublishLabelOptions( label='Duration', palette_index=PaletteColor.gray, y_axis=1, # right y-axis plot_type=PlotType.line_chart, # override of main chart type for 1 metric value_unit='Millisecond' # SignalFx will automatically convert units to human-readable format ) ) \ .with_axes([ AxisOption(label="Count", min=0), # left Y-axis AxisOption(label="Latency", min=0) # right Y-axis ]) \ .with_program( Program( Plot( assigned_name="A", signal_name="Invocations", # metric name filter=And( Filter("FunctionName", function_name), Filter("namespace", "AWS/Lambda"), Filter("stat", "sum") # CloudWatch sends several stats for each metric so you need to filter ), rollup=RollupType.sum, fx=[Sum(by=["aws_account_id", "FunctionName"])], label="Invocations"),