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)
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
 .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"),