The Report
custom resource is used to manage the execution and status of reports.
Metering produces reports derived from usage data sources which can be used in further analysis and filtering.
A single Report
resource represents a report which is updated with new information according to a schedule.
Reports with a spec.schedule
field set are always running, and will track what time periods it has collected data for, ensuring that if Metering is shutdown or unavailable for an extended period of time, it will backfill the data starting where it left off.
If the schedule is unset, then the Report will run once for the time specified by the reportingStart and reportingEnd.
By default, reports will wait for ReportDataSources to have progressed in their import process to cover the report period being processed.
If the report has a schedule, it will wait until the period currently being processed has been covered by the import process.
The following example Report will contain information on every Pod's CPU requests, and will run every hour, adding the last hours worth of data each time it runs.
apiVersion: metering.openshift.io/v1
kind: Report
metadata:
name: pod-cpu-request-hourly
spec:
query: "pod-cpu-request"
reportingStart: "2019-07-01T00:00:00Z"
schedule:
period: "hourly"
hourly:
minute: 0
second: 0
The following example report will contain information on every Pod's CPU requests for all of July. After completion it does not run again.
apiVersion: metering.openshift.io/v1
kind: Report
metadata:
name: pod-cpu-request-hourly
spec:
query: "pod-cpu-request"
reportingStart: "2019-07-01T00:00:00Z"
reportingEnd: "2019-07-31T00:00:00Z"
Names the ReportQuery
used to generate the report.
The report query controls the schema of the report as well how the results are processed.
query
is a required field.
Use kubectl
to obtain a list of available ReportQuery
objects:
$ kubectl -n $METERING_NAMESPACE get reportqueries
NAME AGE
cluster-cpu-capacity 23m
cluster-cpu-capacity-raw 23m
cluster-cpu-usage 23m
cluster-cpu-usage-raw 23m
cluster-cpu-utilization 23m
cluster-memory-capacity 23m
cluster-memory-capacity-raw 23m
cluster-memory-usage 23m
cluster-memory-usage-raw 23m
cluster-memory-utilization 23m
cluster-persistentvolumeclaim-request 23m
namespace-cpu-request 23m
namespace-cpu-usage 23m
namespace-cpu-utilization 23m
namespace-memory-request 23m
namespace-memory-usage 23m
namespace-memory-utilization 23m
namespace-persistentvolumeclaim-request 23m
namespace-persistentvolumeclaim-usage 23m
node-cpu-allocatable 23m
node-cpu-allocatable-raw 23m
node-cpu-capacity 23m
node-cpu-capacity-raw 23m
node-cpu-utilization 23m
node-memory-allocatable 23m
node-memory-allocatable-raw 23m
node-memory-capacity 23m
node-memory-capacity-raw 23m
node-memory-utilization 23m
persistentvolumeclaim-capacity 23m
persistentvolumeclaim-capacity-raw 23m
persistentvolumeclaim-phase-raw 23m
persistentvolumeclaim-request 23m
persistentvolumeclaim-request-raw 23m
persistentvolumeclaim-usage 23m
persistentvolumeclaim-usage-raw 23m
persistentvolumeclaim-usage-with-phase-raw 23m
pod-cpu-request 23m
pod-cpu-request-raw 23m
pod-cpu-usage 23m
pod-cpu-usage-raw 23m
pod-memory-request 23m
pod-memory-request-raw 23m
pod-memory-usage 23m
pod-memory-usage-raw 23m
ReportQueries with the -raw
suffix are used by other ReportQueries to build more complex queries, and should not be used directly for reports.
namespace-
prefixed queries aggregate Pod CPU/memory requests by namespace, providing a list of namespaces and their overall usage based on resource requests.
pod-
prefixed queries are similar to 'namespace-' prefixed, but aggregate information by Pod, rather than namespace. These queries include the Pod's namespace and node.
node-
prefixed queries return information about each node's total available resources.
aws-
prefixed queries are specific to AWS. Queries suffixed with -aws
return the same data as queries of the same name without the suffix, and correlate usage with the EC2 billing data.
The aws-ec2-billing-data
report is used by other queries, and should not be used as a standalone report. The aws-ec2-cluster-cost
report provides a total cost based on the nodes included in the cluster, and the sum of their costs for the time period being reported on.
For a complete list of fields each report query produces, use kubectl
to get the object as YAML, and check the columns
field:
$ kubectl -n $METERING_NAMESPACE get reportqueries namespace-memory-request -o yaml
apiVersion: metering.openshift.io/v1
kind: ReportQuery
metadata:
name: namespace-memory-request
labels:
operator-metering: "true"
spec:
columns:
- name: period_start
type: timestamp
unit: date
- name: period_end
type: timestamp
unit: date
- name: namespace
type: varchar
unit: kubernetes_namespace
- name: pod_request_memory_byte_seconds
type: double
unit: byte_seconds
The schedule block defines when the report runs. The main fields in the schedule
section are period
, and then depending on the value of period
, the fields hourly
, daily
, weekly
and monthly
allow you to fine-tune when the report runs.
For example, if period
is set to weekly
, you can add a weekly
key to the schedule
block. The following example will run once a week on Wednesday, at 1 PM.
...
schedule:
period: "weekly"
weekly:
dayOfWeek: "wednesday"
hour: 13
Valid values of period
are listed below, and the options available to set for a given period are also listed.
hourly
minute
second
daily
hour
minute
second
weekly
dayOfWeek
hour
minute
second
monthly
dayOfMonth
hour
minute
second
cron
expression
Generally, the hour
, minute
, second
fields control when in the day the report runs, and dayOfWeek
/dayOfMonth
control what day of the week, or day of month the report runs on, if it's a weekly or monthly report period.
For each of these fields, there is a range of valid values:
hour
is an integer value between 0-23.minute
is an integer value between 0-59.second
is an integer value between 0-59.dayOfWeek
is a string value that expects the day of the week (spelled out).dayOfMonth
is an integer value between 1-31.
For cron periods, normal cron expressions are valid:
expression: "*/5 * * * *"
To support running a Report against existing data, you can set the spec.reportingStart
field to a RFC3339 timestamp to tell the Report to run according to its schedule
starting from reportingStart
rather than the current time.
One important thing to understand is that this will result in the reporting-operator running many queries in succession for each interval in the schedule that's between the reportingStart
time and the current time.
This could be thousands of queries if the period is less than daily and the reportingStart
is more than a few months back.
If reportingStart
is left unset, the Report will run at the next full reportingPeriod after the time the report is created.
As an example of how to use this field, if you had data already collected dating back to January 1st, 2019 which you wanted to be included in your Report, you could create a report with the following values:
apiVersion: metering.openshift.io/v1
kind: Report
metadata:
name: pod-cpu-request-hourly
spec:
query: "pod-cpu-request"
schedule:
period: "hourly"
reportingStart: "2019-01-01T00:00:00Z"
To configure a Report to only run until a specified time, you can set the spec.reportingEnd
field to an RFC3339 timestamp.
The value of this field will cause the Report to stop running on its schedule after it has finished generating reporting data for the period covered from its start time until reportingEnd
.
Because a schedule will most likely not align with reportingEnd, the last period in the schedule will be shortened to end at the specified reportingEnd time.
If left unset, then the Report will run forever, or until a reportingEnd
is set on the Report.
For example, if you wanted to create a report that runs once a week for the month of July:
apiVersion: metering.openshift.io/v1
kind: Report
metadata:
name: pod-cpu-request-hourly
spec:
query: "pod-cpu-request"
schedule:
period: "weekly"
reportingStart: "2019-07-01T00:00:00Z"
reportingEnd: "2019-07-31T00:00:00Z"
Add the expiration field to set a retention period on a scheduled metering Report. You can avoid manually removing the Report by setting the expiration duration value. The retention period is equal to the Report creationDate plus the expiration
duration. The Report is removed from the cluster at the end of the retention period if no other Reports or ReportQueries depend on the expiring Report. Deleting the Report from the cluster can take several minutes.
Setting the expiration field is not recommended for roll-up or aggregated reports. If a Report is depended upon by other Reports or ReportQueries, then the Report is not removed at the end of the retention period. You can view the reporting-operator logs at debug level for the timing output around a Report retention decision.
For example, the following scheduled Report is deleted 30 minutes after the metadata.creationDate
of the Report:
apiVersion: metering.openshift.io/v1
kind: Report
metadata:
name: pod-cpu-request-hourly
spec:
query: "pod-cpu-request"
schedule:
period: "weekly"
reportingStart: "2020-09-01T00:00:00Z"
expiration: "30m"
Valid time units for the expiration duration are ns, us (or µs), ms, s, m, and h.
The expiration retention period for a Report is not precise and works on the order of several minutes, not nanoseconds.
When runImmediately
is set to true
, the report will be run immediately. This behavior ensures that the report is immediately processed and queued without requiring additional scheduling parameters.
Note: When
runImmediately
is set totrue
you must set areportingEnd
andreportingStart
value.
The spec.inputs
field of a Report can be used to override or set values defined in a ReportQuery's spec.inputs field.
It is a list of name-value pairs:
spec:
inputs:
- name: "NamespaceCPUUsageReportName"
value: "namespace-cpu-usage-hourly"
The name
of an input must exist in the ReportQuery's inputs
list.
The value
of the input must be the correct type for the input's type
.
For an example of how this can be used, see it in action in a roll-up report. For more details on how inputs can be specified read the Specifying Inputs section of the ReportQueries documentation.
Report data is stored in the database much like metrics themselves, and can thus be used in aggregated or roll-up reports. A simple use case for a roll-up report is to spread the time required to produce a report over a longer period of time: instead of requiring a monthly report to query and add all data over an entire month, the task can be split into daily reports that each run over a thirtieth of the data.
A custom roll-up report requires a custom report query.
The ReportQuery template processor provides a function: reportTableName
that can get the necessary table name from a report name.
Below is a snippet taken from a built-in query:
# Taken from pod-cpu.yaml
spec:
...
inputs:
- name: ReportingStart
type: time
- name: ReportingEnd
type: time
- name: NamespaceCPUUsageReportName
type: Report
- name: PodCpuUsageRawDataSourceName
type: ReportDataSource
default: pod-cpu-usage-raw
...
query: |
...
{|- if .Report.Inputs.NamespaceCPUUsageReportName |}
namespace,
sum(pod_usage_cpu_core_seconds) as pod_usage_cpu_core_seconds
FROM {| .Report.Inputs.NamespaceCPUUsageReportName | reportTableName |}
...
# aggregated-report.yaml
spec:
query: "namespace-cpu-usage"
inputs:
- name: "NamespaceCPUUsageReportName"
value: "namespace-cpu-usage-hourly"
For more information on setting up a roll-up report, see the roll-up report guide.
The execution of a scheduled report can be tracked using its status field. Any errors occurring during the preparation of a report will be recorded here.
The status
field of a Report
currently has two fields:
conditions
: Conditions is a list of conditions, each of which have atype
,status
,reason
, andmessage
field. Possible values of a condition'stype
field areRunning
andFailure
, indicating the current state of the scheduled report. Thereason
indicates why itscondition
is in its current state with thestatus
being eithertrue
,false
orunknown
. Themessage
provides a human readable indicating why the condition is in the current state. For detailed information on thereason
values seepkg/apis/metering/v1/util/report_util.go
.lastReportTime
: Indicates the time Metering has collected data up to.