Azure-Samples / monitor-dotnet-metrics-api

Code sample of the Azure Monitor metrics API using the .Net SDK
MIT License
13 stars 10 forks source link

Unable to retrieve metrics with queries #3

Open Martindukz opened 7 years ago

Martindukz commented 7 years ago

When I try to run the: `var metricNames = "name.value eq 'CpuPercentage'"; // could be concatenated with " or name.value eq ''" ...

        // Time grain is optional when metricNames is present
        string timeGrain = " and timeGrain eq duration'PT5M'";

        // Defaulting to 3 hours before the time of execution for these datetimes
        string startDate = string.Format(" and startTime eq {0}", DateTime.Now.AddHours(-3).ToString("o"));
        string endDate = string.Format(" and endTime eq {0}", DateTime.Now.ToString("o"));

        var odataFilterMetrics = new ODataQuery<Metric>(
            string.Format(
                "{0}{1}{2}{3}",
                metricNames,
                timeGrain,
                startDate,
                endDate));

        Write("Call with filter parameter (i.e. $filter = {0})", odataFilterMetrics);
        var metrics = await readOnlyClient.Metrics.ListAsync(resourceUri: resourceUri, odataQuery: odataFilterMetrics, cancellationToken: CancellationToken.None);`

I get a: Operation returned an invalid status code 'BadRequest'

The query sent looks like this: Call with filter parameter (i.e. $filter = $filter=name.value eq 'CpuPercentage' and timeGrain eq duration'PT5M' and startTime eq 2017-07-01T17:32:47.5198212+02:00 and endTime eq 2017-07-01T20:32:47.5208119+02:00)

Running:

var metrics = (await readOnlyClient.Metrics.ListAsync(resourceUri: resourceUri, cancellationToken: CancellationToken.None)).ToList(); Console.WriteLine("Metrics found: " + metrics.Count);

Returns metrics without exception. Although it only returns 'Cpu Percentage' metrics. For some reason...

Any idea as to what the cause is?

tomaszgawlik commented 7 years ago

@Martindukz I've had the same issue, but I was able to debug the SDK. The problem is example code will work but only if your current time zone is UTC.

Not UTC time zone DateTime.Now.ToString("o") will produce: "2017-10-25T07:20:39.3888277+01:00"

UTC time zone will produce: "2017-10-25T06:26:49.2295636Z"

So the solution is to use utc date time:

        string startDate = string.Format(" and startTime eq {0}", DateTime.UtcNow.AddHours(-3).ToString("o"));
        string endDate = string.Format(" and endTime eq {0}", DateTime.UtcNow.ToString("o"));
vascofernandes commented 6 years ago

@tomaszgawlik having the same problem and you solution did not work for me.

I am able to get a list of metrics and get data, but when making a request with a filter it does not work.

Request:

https://management.azure.com//subscriptions/x-x-x-x-x/resourceGroups/xxxxxxx/providers/Microsoft.Logic/workflows/xxxxxxxx/providers/microsoft.insights/metrics?$filter=name.value eq 'RunsStarted' and timeGrain eq duration'PT5M' and startTime eq 2018-03-25T12:04:01Z and endTime eq 2018-03-25T15:04:01Z&api-version=2018-01-01

Response:

{"code":"BadRequest","message":"only supports conditions of the form ' eq ' : name.value eq 'RunsStarted' and timeGrain eq duration'PT5M' and startTime eq 2018-03-25T12:04:01Z and endTime eq 2018-03-25T15:04:01Z"}

An example of a call that works:

metrics = await readOnlyClient.Metrics.ListAsync(
     resourceUri: resourceUri,
     timespan: timeSpan,
     interval: TimeSpan.FromMinutes(1),
     metricnames: "RunsStarted",
     resultType: ResultType.Data,
     cancellationToken: CancellationToken.None);

https://management.azure.com//subscriptions/x-x-x-x-x/resourceGroups/xxxxxxx/providers/Microsoft.Logic/workflows/xxxxxx/providers/microsoft.insights/metrics?timespan=2018-03-25T12:15:54.5048337Z/2018-03-25T15:15:54.5048397Z&interval=PT1M&metricnames=RunsStarted&resultType=Data&api-version=2018-01-01

chenzheng1988 commented 5 years ago

SDK:Microsoft.Azure.Management.Monitor Version:0.16.0-preview

When I call readOnlyClient.Metrics.ListAsync(), I also report an error:

{"code": "BadRequest", "message": "only conditions of the Form'< name > EQ < value > are allowed, where < name >='time grain','startTime','endtime','name. value','aggregationType','debug region': name. vaule EQ'centage CPU' and timegrain q'1M and starteq 2019-01-20 and EndQ 2019-01-21}

I use the request address in postman:https://management.chinacloudapi.cn/resourceID/providers/microsoft.insights/metrics?$filter=name.vaule eq'Percentage CPU'and timeGrain EQ duration'PT1M'and startTime EQ 2019-01-20 and endTime EQ 2019-01-21&api-version=2016-09-01-01-20.

The same mistake was reported.

Finally, I found that the $filter parameter in the request address could be successfully invoked by adding or spaces after the $filter parameter. Reference is made to the following: Https://management.chinacloudapi.cn/resourceID/providers/microsoft.insights/metrics?$filter=name.vaule EQ'Percentage CPU'and timeGrain EQ duration'PT1M' and startTime EQ 2019-01-20 and endTime EQ 2019-01-21 & api-version = 2016-09-01-01 Https://management.chinacloudapi.cn/resourceID/providers/microsoft.insights/metrics?$filter = name.vaule eq'Percentage CPU'and timegrain EQ duration'PT1M'and startTime EQ 2019-01-20 and endTime EQ 2019-01-21 & api-version = 2016-09-01-01

But in SDK, ODataQuery is encapsulated with $filter, which cannot be changed to `$filter.

chenzheng1988 commented 5 years ago

This issue still exists. Who can help us to see it?

Dennizzzzz commented 4 years ago

I had simular problems with this example just now. I managed to get it to work by first: changing the next two lines:

string startDate = string.Format(" and startTime eq {0}", DateTime.Now.AddHours(-3).ToString("o")).Replace("+", "%2b");
string endDate = string.Format(" and endTime eq {0}", DateTime.Now.ToString("o")).Replace("+", "%2b");

second: change

var metricNames = "name.value eq 'CpuPercentage'";

into:

var metricNames = "name.value eq 'cpu_percent'";
robbendavid commented 2 years ago

I also had to change the string formatting like @Dennizzzzz did but the metric name was fine as is.

raasmasood commented 2 years ago

@Martindukz I've had the same issue, but I was able to debug the SDK. The problem is example code will work but only if your current time zone is UTC.

Not UTC time zone DateTime.Now.ToString("o") will produce: "2017-10-25T07:20:39.3888277+01:00"

UTC time zone will produce: "2017-10-25T06:26:49.2295636Z"

So the solution is to use utc date time:

        string startDate = string.Format(" and startTime eq {0}", DateTime.UtcNow.AddHours(-3).ToString("o"));
        string endDate = string.Format(" and endTime eq {0}", DateTime.UtcNow.ToString("o"));

this worked for me