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 inoptions
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 inoptions
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
-
-
Not supported in SolarWinds Observability PromQL.
-
-
-
There is no direct equivalent in SolarWinds Observability PromQL.
-
Instead, there is a
bottomk
function, that returns up tok
lowest data points for each existing timestamp. -
Example:
bottomk(5, min_over_time(system.cpu.user[1h]))
-
-
-
In SolarWinds Observability PromQL, the equivalent is the
ceil
function.
-
-
-
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])
-
-
-
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.*"}
-
-
-
This is comparable to the function
fill
in SolarWinds Observability PromQL. -
The
last
value is comparable to the functionlast_fill
. -
Examples:
AppOptics: fill(s("memory_used",{"@host": "prod.web*"}), {value: "0"})
SolarWinds Observability: fill(0, memory_used{\@host=~"prod\.web.*"})
-
-
-
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
-
-
-
In SolarWinds Observability PromQL, this is equivalent to the
floor
function.
-
-
-
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.*"}))
-
-
-
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.*"})
-
-
-
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)
-
-
-
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)
-
-
-
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])
-
-
-
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.*"}
-
-
-
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
-
-
-
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
-
-
-
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.*"}
-
-
-
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)
-
-
-
There is no direct equivalent in SolarWinds Observability PromQL.
-
Instead, there is a
topk
function, which returns up tok
largest data points for each existing timestamp. -
Example:
topk(5, max_over_time(system.cpu.user[1h]))
-
-
-
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])
-
-
-
In SolarWinds Observability PromQL, this is comparable to the function
fill
with a value of0
in the first parameter.
-
-
-
In SolarWinds Observability PromQL, this is comparable to the
by
clause within functions likesum
,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.*"})
-
-
-
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
-