Documentation forSolarWinds Observability SaaS

Migrate composite metrics from AppOptics to SolarWinds Observability

If you are migrating from AppOptics to SolarWinds Observability SaaS, be aware of the differences between composite metrics in AppOptics and composite metrics in SolarWinds Observability.

Generator Functions

  • series(metric, tag, options={})

    • Composite metrics in SolarWinds Observability have the concepts of time series, sets, filters, and aggregation.

    • Unlike AppOptics, composite metrics are defined in SolarWinds Observability by providing a PromQL query. The wrapping syntax series(...) is not used. All transformation functions take as input either a metric name, a constant, or the result of another transformation function.

    • This means that the operations are applied to metrics in a different order:

      In AppOptics, custom bucketing with aggregation is applied first and then transformation functions. The resulting data points are then bucketed according to the needs of the UI.

      In SolarWinds Observability PromQL, the order is reversed. Data points are first bucketed into averages of one-second intervals to ensure their alignment in time. Then the transformation functions are applied. And then the resulting data points are bucketed according to the needs of the UI.

    • The function parameter in options can be mitigated in SolarWinds Observability PromQL using <aggregation>_over_time functions along with $bucket_interval when querying a range vector.

    • Also, unlike AppOptics, in SolarWinds Observability there is no * filter because all possible sets are returned by default. If more fine-grained filtering is needed, you can use RE2 RegEx instead.

      Limitation: SolarWinds Observability does not support filtering of metric names. Those must be spelled out explicitly in the query.

    • If any of the PromQL functions require a value (for example, a range), the value is provided as part of the query, according to the PromQL syntax rules. Instead of hard-coding some of the time values, they can be replaced by variables. See Variable substitution for details.

    • Replacing attribute filters by variables is not supported. However, any such filters selected on UI will automatically be applied to all time series of all metrics in the composite metric.

    • While the traditional PromQL does not support metric names with . and / symbols, in SolarWinds Observability they are supported.

    • The period parameter in options is not supported. In SolarWinds Observability PromQL, the bucket interval is always driven by the UI. It is not possible to customize it.

    • Examples:

      AppOptics: series("foo.bar.baz", {})
      SolarWinds Observability: foo.bar.baz
      AppOptics: series("foo.bar.baz", {"name":"prod.*"})
      SolarWinds Observability: foo.bar.baz{name=~"prod\..*"}
      AppOptics: series("foo.bar.*", {"name":"prod.*"})
      SolarWinds Observability: Not supported
      AppOptics: series("foo.bar.baz", "%")
      SolarWinds Observability: foo.bar.baz
      AppOptics: series("foo.bar.baz", {}, { function:"mean" })
      SolarWinds Observability: avg_over_time(foo_bar_baz[$bucket_interval])
      AppOptics: series("foo.bar.baz", {}, { period:"3600", function:"mean" })
      SolarWinds Observability:

      Not supported

Transformation Functions

  • abs(set[])

    • Not supported in SolarWinds Observability PromQL.

  • bottom(set[], options={})

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • Instead, there is a bottomk function, that returns up to k lowest data points for each existing timestamp.

    • Example:

      bottomk(5, min_over_time(system.cpu.user[1h]))

  • ceiling(set[])

    • In SolarWinds Observability PromQL, the equivalent is the ceil function.

  • derive(set[], options={})

    • In SolarWinds Observability PromQL, this is comparable to the increase function.

    • The option detect_reset:"false" is not supported. PromQL always adjusts for resets.

    • The diff in value for each data point is not calculated compared to a previous data point, but compared to a data point for a specified time in the past. It is beneficial to use the $bucket_interval variable to compare the diff of individual buckets displayed in the UI.

    • Example:

      increase(AWS.Billing.EstimatedCharges.total{region=~".+"}[$bucket_interval])

  • divide(set[2])

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • However, a similar behavior can be achieved using the / operator. It takes a set of series for each operand. Then, based on their attributes, it tries to find matching series on both sides. For each pair found, it returns a new series where each data point is a result of division between data points of the original series. Series or data points that could not be matched are ignored.

    • Examples:

      AppOptics:
      divide([
        sum(s("memory_used",{"@host": "prod.web*"})),
        sum(s("memory_total",{"@host": "prod.web*"}))])
      SolarWinds Observability: memory_used{\@host=~"prod\.web.*"} / memory_total{\@host=~"prod\.web.*"}

      If the metrics do not have the exact same attributes (for example, memory_total has an additional attribute that should be ignored during the series matching), they can be filtered:

      SolarWinds Observability: memory_used{\@host=~"prod\.web.*"} / on (@host) memory_total{\@host=~"prod\.web.*"}
  • fill(set[], options={})

    • This is comparable to the function fill in SolarWinds Observability PromQL.

    • The last value is comparable to the function last_fill.

    • Examples:

      AppOptics: fill(s("memory_used",{"@host": "prod.web*"}), {value: "0"})
      SolarWinds Observability: fill(0, memory_used{\@host=~"prod\.web.*"})
  • filter(set[], options)

    • In SolarWinds Observability PromQL, this is comparable to comparison binary operators:

      • == (equal)
      • != (not-equal)
      • > (greater-than)
      • < (less-than)
      • >= (greater-or-equal)
      • <= (less-or-equal)
    • The behavior differs slightly. The filter function in AppOptics filters time series while comparison binary operators in SolarWinds Observability PromQL filter data points.

    • Examples:

      AppOptics:
      filter(
        s("AWS.ApplicationELB.TargetResponseTime",
          {"name": "*"},
          {function:"mean"}),
          {gt:"0.025",function:"min"}
      )
      SolarWinds Observability: avg_over_time(AWS_ApplicationELB_TargetResponseTime{name=~".+"}[$bucket_interval]) > 0.025
  • floor(set[])

    • In SolarWinds Observability PromQL, this is equivalent to the floor function.

  • integrate(set[])

    • This is comparable to the function integrate in SolarWinds Observability PromQL.

    • Examples:

      AppOptics: integrate(sum(s("AWS.EC2.CPUCreditUsage", {"name": "prodvpc*"}, { period:"60", function:"sum" })))
      SolarWinds Observability: integrate(sum(AWS.EC2.CPUCreditUsage{name=~"prodvpc.*"}))
  • last_fill(set[])

    • This is comparable to the function last_fill in SolarWinds Observability PromQL.

    • Examples:

      AppOptics: last_fill(s("memory_used",{"@host": "prod.web*"}), {period: "60"})
      SolarWinds Observability: last_fill(memory_used{\@host=~"prod\.web.*"})
  • max(set[])

    • In SolarWinds Observability PromQL, this is comparable to the function max, which returns the largest data point for each existing timestamp.

    • If you need to find maximums for multiple series, data points can be grouped by the series' labels.

    • Examples:

      AppOptics: max(s("foo.metric",{"@host":"*"},{function:"max"}))
      SolarWinds Observability: max(foo.metric{\@host=~".+"}) by (@host)
  • mean(set[])

    • In SolarWinds Observability PromQL, this is comparable to the function avg, which returns the average of the data points for each existing timestamp.

    • If you need to find averages for multiple series, data points can be grouped by the series' labels.

    • Examples:

      AppOptics: mean(s("foo.metric",{"@host":"*"}))
      SolarWinds Observability: avg(foo.metric{\@host=~".+"}) by (@host)
  • min(set[])

    • In SolarWinds Observability PromQL, this is comparable to the function min, which returns the smallest data point for each existing timestamp.

    • If you need to find minimums for multiple series, data points can be grouped by the series' labels.

    • Examples:

      AppOptics: min(s("foo.metric",{"@host":"*"}))
      SolarWinds Observability: min(foo.metric{\@host=~".+"}) by (@host)
  • moving_average(set[], options={})

    • In SolarWinds Observability PromQL, this is comparable to the function avg_over_time, which returns the average of multiple data points in the past for each existing timestamp. However, instead of the number of data points, it takes a time range.

    • Like other functions in SolarWinds Observability PromQL, it cannot take an already aggregated series as an input.

    • Examples:

      AppOptics:
      moving_average(
        max(s("api.auth.time.p99",{"@host":"*"},{function:"max"})), {size:"5"})
      SolarWinds Observability: avg_over_time(api.auth.time.p99{\@host=~".+"}[5m])
  • multiply(set[])

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • However, a similar behavior can be achieved using the * operator. It takes a set of series for each operand. Then, based on their attributes, it tries to find matching series on both sides. For each pair found, it returns a new series where each data point is the result of multiplication between data points of the original series. Series or data points that could not be matched are ignored.

    • Examples:

      AppOptics:
      multiply([
        sum(s("api.cache.get.misses",{"@host": "prod.web*"})),
        sum(s("api.cache.get.time",{"@host": "prod.web*"}))])
      SolarWinds Observability: api.cache.get.misses{\@host=~"prod\.web.*"} * api.cache.get.time{\@host=~"prod\.web.*"}

      If the metrics do not have the exact same attributes (for example, memory_total has an additional attribute that should be ignored during the series matching), they can be filtered:

      SolarWinds Observability: memory_used{\@host=~"prod\.web.*"} * on ("@host") memory_total{\@host=~"prod\.web.*"}
  • rate(set[], options = {})

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • In SolarWinds Observability PromQL, to convert a rate metric to another unit, you need to know its periodicity. It cannot be detected automatically.

    • Examples:

      AppOptics: rate(s("http.requests.count", {"@host":"*"}, {period: "300"}), {duration:"3600"})
      SolarWinds Observability: http.requests.count{\@host=~".+"} / 300 * 3600
  • scale(set[], options)

    • In SolarWinds Observability PromQL, the factor has to be provided as a number, not as a fraction.

    • Examples:

      AppOptics: scale(s("AppOptics.memory.memory.used", {"@host":"*"}), {factor:"1/10"})
      SolarWinds Observability: AppOptics.memory.memory.used{\@host=~".+"} * 0.1
  • subtract(set[2])

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • However, a similar behavior can be achieved using the - operator. It takes a set of series for each operand. Then, based on their attributes, it tries to find matching series on both sides. For each pair found, it returns a new series where each data point is a result of subtraction between data points of the original series. Series or data points that could not be matched are ignored.

    • Examples:

      AppOptics:
      subtract([
        sum(s("foo",{"@host": "prod.web*"})),
        sum(s("bar",{"@host": "prod.web*"}))
      ])
      SolarWinds Observability: foo{\@host=~"prod\.web.*"} - bar{\@host=~"prod\.web.*"}

      If the metrics do not have the exact same attributes (for example, bar has an additional attribute that should be ignored during the series matching), they can be filtered:

      SolarWinds Observability: foo{\@host=~"prod\.web.*"} - on (@host) bar{\@host=~"prod\.web.*"}
  • sum(set[])

    • In SolarWinds Observability PromQL, this is comparable to the function sum, which returns the sum of the data points for each existing timestamp.

    • If you need to find sums for multiple series, data points can be grouped by the series' labels.

    • Examples:

      AppOptics: sum(s("foo.metric",{"@host":"*"}))
      SolarWinds Observability: sum(foo.metric{\@host=~".+"}) by (@host)
  • top(set[], options={})

    • There is no direct equivalent in SolarWinds Observability PromQL.

    • Instead, there is a topk function, which returns up to k largest data points for each existing timestamp.

    • Example:

      topk(5, max_over_time(system.cpu.user[1h]))

  • window(set[], options={})

    • In SolarWinds Observability PromQL, this is comparable to the min_over_time/max_over_time/sum_over_time/avg_over_time functions, which return the aggregation of multiple data points in the past for each existing timestamp. However, instead of the number of data points, it takes a time range.

    • Like other functions in SolarWinds Observability PromQL, it cannot take an already aggregated series as an input.

    • Examples:

      AppOptics: window(max(s("api.auth.time.p99", {"@host":"*"})), {size: "5", function:"median"})
      SolarWinds Observability: avg_over_time(api.auth.time.p99{\@host=~".+"}[5m])
  • zero_fill(set[])

    • In SolarWinds Observability PromQL, this is comparable to the function fill with a value of 0 in the first parameter.

  • group_by(tags, set[])

    • In SolarWinds Observability PromQL, this is comparable to the by clause within functions like sum, avg, max, and so forth.

    • Examples:

      AppOptics: group_by("region", sum(series("AWS.ELB.HTTPCode_Backend_2XX", {"region" : "us*"})))
      SolarWinds Observability: sum by (region) (AWS_ELB_HTTPCode_Backend_2XX{region=~"us.*"})
  • timeshift(shifts, set[])

    • In SolarWinds Observability PromQL, this is comparable to the offset modifier.

    • Examples:

      AppOptics: timeshift("60s",s("foo.total", {"@host":"*"},{period:"60"}))
      SolarWinds Observability: foo.total{\@host=~".*"} offset 60s