Public/Get-PCOciMetric.ps1

function Get-PCOciMetric {
    <#
    .SYNOPSIS
        Reads Monitoring datapoints for one metric over a window and writes them, raw, to a metrics file.

    .DESCRIPTION
        One metric of one namespace (oci_computeagent by default) at an interval (1h by default) with a statistic
        (mean by default), from the tenancy root with every compartment beneath it, in every subscribed region or
        the ones named. Every datapoint the service returns is written as it came and nothing is derived (D-014):
        summarising is Measure-PCOciMetric, a separate step over the file. A window longer than seven days (one
        day at the one-minute interval) is read in several calls per region and the streams are stitched by their
        dimensions. The run report is written beside the file.

    .PARAMETER Name
        The metric: CpuUtilization, MemoryUtilization, DiskBytesRead, DiskBytesWritten, NetworksBytesIn,
        NetworksBytesOut, or any other name the namespace emits.

    .PARAMETER Namespace
        The metric namespace. Default oci_computeagent.

    .PARAMETER Interval
        The interval the service aggregates over: 1m, 5m, 1h or 1d. Default 1h.

    .PARAMETER Statistic
        mean, max, min, sum, count, rate, p50, p90, p95 or p99. Default mean.

    .PARAMETER Query
        A query in the service's own language, in place of the one built from -Name, -Interval and -Statistic.

    .PARAMETER Start
        The start of the window. Default: thirty days before -End.

    .PARAMETER End
        The end of the window, exclusive. Default: midnight UTC today.

    .PARAMETER CompartmentId
        The compartment to read from. Default: the tenancy root, with every compartment beneath it.

    .PARAMETER Region
        The regions to read. Default: every subscribed region.

    .EXAMPLE
        Get-PCOciMetric -Name CpuUtilization -Path .\data\metrics\cpu.json -Deterministic
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([pscustomobject], [PowerCraft.OCI.Core.Metrics.MetricSeries])]
    param(
        [PowerCraft.OCI.Core.Identity.OciContext]$Context,
        [Parameter(Mandatory, Position = 0)][string]$Name,
        [string]$Namespace = 'oci_computeagent',
        [string]$ResourceGroup,
        [ValidateSet('1m', '5m', '1h', '1d')][string]$Interval = '1h',
        [ValidateSet('mean', 'max', 'min', 'sum', 'count', 'rate', 'p50', 'p90', 'p95', 'p99')][string]$Statistic = 'mean',
        [string]$Query,
        [datetime]$Start,
        [datetime]$End,
        [string]$CompartmentId,
        [string[]]$Region,
        [string]$Path = (Join-Path (Get-Location).Path 'metrics.json'),
        [switch]$Deterministic,
        [string]$ReportPath,
        [switch]$PassThru,
        [switch]$Force
    )

    $ctx = Get-PCOciContextOrThrow -Context $Context
    if ((Test-Path -LiteralPath $Path) -and -not $Force) { throw "A file already exists at '$Path'. Use -Force to overwrite it." }
    if (-not $ReportPath) { $ReportPath = [IO.Path]::ChangeExtension($Path, '.report.json') }

    $today = [DateTime]::UtcNow.Date
    if (-not $PSBoundParameters.ContainsKey('End')) { $End = $today }
    if (-not $PSBoundParameters.ContainsKey('Start')) { $Start = $End.AddDays(-30) }

    $metricQuery = [PowerCraft.OCI.Core.Metrics.MetricQuery]::new()
    $metricQuery.TenancyId = $ctx.TenancyId
    if ($CompartmentId) { $metricQuery.CompartmentId = $CompartmentId }
    $metricQuery.Namespace = $Namespace
    $metricQuery.Name = $Name
    if ($ResourceGroup) { $metricQuery.ResourceGroup = $ResourceGroup }
    $metricQuery.Interval = $Interval
    $metricQuery.Statistic = $Statistic
    if ($Query) { $metricQuery.Query = $Query }
    $metricQuery.Start = [DateTimeOffset]::new([DateTime]::SpecifyKind($Start, [DateTimeKind]::Utc))
    $metricQuery.End = [DateTimeOffset]::new([DateTime]::SpecifyKind($End, [DateTimeKind]::Utc))
    if ($Region) { $metricQuery.Regions.AddRange([string[]]$Region) }

    $plan = [PowerCraft.OCI.Core.Metrics.MetricPlanner]::Plan($metricQuery, [DateTimeOffset]::UtcNow)
    if (-not $PSCmdlet.ShouldProcess($Path, "Read $($metricQuery.EffectiveQuery()) over $($plan.Windows.Count) window(s)")) { return }

    $report = [PowerCraft.OCI.Core.Report.RunReport]::new()
    $report.Verb = 'Get-PCOciMetric'
    $started = [DateTimeOffset]::UtcNow
    $report.StartedAt = $started
    $series = [PowerCraft.OCI.Core.Gateways.MetricGateway]::Run($ctx, $metricQuery, $plan, $report)
    $duration = [long]([DateTimeOffset]::UtcNow - $started).TotalMilliseconds
    $report.DurationMs = $duration

    [PowerCraft.OCI.Core.Metrics.MetricWriter]::Write($series, $Path, [bool]$Deterministic)
    $report.Write($ReportPath, [bool]$Deterministic)
    foreach ($w in $report.Warnings) { Write-Warning $w }
    if (-not $series.Complete) { Write-Warning ("The metric series is incomplete: {0} failure(s). See '{1}'." -f $report.Failures.Count, $ReportPath) }

    if ($PassThru) { return $series }
    [pscustomobject]@{
        MetricsPath = (Resolve-Path -LiteralPath $Path).Path
        ReportPath  = (Resolve-Path -LiteralPath $ReportPath).Path
        Complete    = $series.Complete
        Namespace   = $series.Namespace
        Name        = $series.Name
        Query       = $series.Query
        Interval    = $series.Interval
        Start       = $series.Start
        End         = $series.End
        Regions     = @($series.Regions)
        Windows     = $plan.Windows.Count
        Streams     = $series.Streams.Count
        Points      = $series.TotalPoints()
        DurationMs  = $duration
    }
}