Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RI from csm-master into csm-anudeeb #77

Merged
merged 58 commits into from
Sep 29, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
cee2328
FW: Fixing the documentation of the properties in the generated code …
gucalder Apr 8, 2015
83d9cec
FW: [Sdk] Rename skuDefinitions to skus
george-moussa Apr 16, 2015
e73d650
WORK: 3595593: [Sdk] Add Milliseconds unit
george-moussa Apr 20, 2015
af3411d
WORK: 3644439: [Sdk][Sku] Remove antares workarounds
george-moussa Apr 20, 2015
2bea3c9
Revert "WORK: 3644439: [Sdk][Sku] Remove antares workarounds"
george-moussa Apr 21, 2015
0c8adf7
WORK: 3587839 [SDK] Support storage analytic metric schema natively i…
davmc Apr 21, 2015
4c18888
Update SDK version
davmc Apr 21, 2015
2c8e250
Fix exception due to TIMESTAMP field type
davmc Apr 23, 2015
f94730e
WORK: 3644439: [Sdk][Sku] Remove antares workarounds
george-moussa Apr 23, 2015
f0ab40d
Azure SDK changes for the hydra changes
jagadisk Apr 24, 2015
d06a022
Revert "WORK: 3587839 [SDK] Support storage analytic metric schema na…
jagadisk Apr 24, 2015
b892a27
Update the SDK version to 0.8.2
jagadisk Apr 24, 2015
9da58c3
Revert "Revert "WORK: 3587839 [SDK] Support storage analytic metric s…
jagadisk Apr 24, 2015
75a43b8
Reverting the revert of the storage analytics.
jagadisk Apr 24, 2015
5479fab
GetMetrics query instance metrics when they are present and aggregate…
vcanaa May 5, 2015
c962957
Increase Insights version to 0.8.4.0
vcanaa May 6, 2015
bbcff80
1. API to get the event categories
jagadisk May 22, 2015
124f3d0
Including the model classes in the project.
jagadisk May 22, 2015
8a322a6
Update the version to 0.8.5-preview
jagadisk May 22, 2015
8783495
API to get Tenant-level events
davmc Jun 5, 2015
97a96d2
Removing files that are not referenced
vcanaa Jul 20, 2015
a41bf6d
Keeping OnetimeGenerated structure the same as generated
vcanaa Jul 20, 2015
57109e4
WORK: 4057941: [Lastest Sku contract][Sdk] Part1: Update non-breaking…
george-moussa Jul 21, 2015
82ee5a8
Fix timestamp parsing in shoebox metrics
vcanaa Jul 22, 2015
773fa54
[ShoeboxV2] MetricsDefinitionsOperations and MetricsOperations
vcanaa Jul 23, 2015
1ae410b
[ShoeboxV2] Fix null pointer exception when aggregating the data from…
vcanaa Jul 29, 2015
3a32541
Disable encoding for GetMetrics (Generated files)
davmc Jul 31, 2015
3a95b1d
BUG: 4305815 : [SDK][legacy passthrough] move towards using extension…
jagadisk Aug 12, 2015
3dc38c9
WORK: 4057941: [SDK][Generic autoscale] Ensure generic autoscale supp…
george-moussa Aug 18, 2015
bf9fcbe
Merge remote-tracking branch 'origin/dev' into dev
davmc Aug 28, 2015
8a7b436
BUG: 4390874 [SDK] Add missing Id field to UsageMetric
davmc Aug 28, 2015
c66ee16
BUG: 4486642 : [ShoeboxV1] Make sure that the new sdk with extensions…
jagadisk Sep 2, 2015
858e324
Version increment
jagadisk Sep 8, 2015
aafa708
Adding support for webhook actions to the Alert sdk
LeoVannelli Sep 10, 2015
a1a6377
BUG: Call to get the metric definition fails.
jagadisk Sep 11, 2015
77fd924
BUG: Call to get the metric definition fails.
jagadisk Sep 11, 2015
b07d61f
Merge branch 'dev' of https://github.com/AuxMon/azure-sdk-for-net int…
jagadisk Sep 11, 2015
db53eb4
Merge branch 'dev' into shoeboxv2
jagadisk Sep 11, 2015
02be46b
Removing the duplicate entries in the csproj (due to merge conflicts)
jagadisk Sep 11, 2015
dc94348
Update the version
jagadisk Sep 11, 2015
5bbd18c
Update the version
jagadisk Sep 11, 2015
829dca6
Merge branch 'dev'
jagadisk Sep 15, 2015
327f123
Remove the code from the old location
jagadisk Sep 15, 2015
7506cde
Overwriting the Insights folder with the latest from the dev branch
jagadisk Sep 15, 2015
9dc40aa
Fix build break with pragma; Account for types supported by AppInsights
jagadisk Sep 16, 2015
0fa6cda
Removing event tests that are not relavant.
jagadisk Sep 16, 2015
8ff3568
Refreshing the SDK with the latest hydra generated files
jagadisk Sep 21, 2015
82adfdc
Search SDK: Removing dependency on JsonConvert.DefaultSettings
brjohnstmsft Sep 24, 2015
3a880ab
Increment the SDK version
jagadisk Sep 24, 2015
a9d90be
Add ListLocations to subscriptions client
vivsriaus Sep 24, 2015
1875570
Merge pull request #73 from MabOneSdk/csm-anudeeb
Sep 25, 2015
0c6a52e
Merge pull request #74 from MabOneSdk/csm-master
Sep 25, 2015
f849555
Merge pull request #1451 from brjohnstmsft/jsonfix-pr
Sep 25, 2015
21db6e5
Merge pull request #1452 from vivsriaus/master
Sep 25, 2015
7eb1056
Merge pull request #1454 from MabOneSdk/release
ogail Sep 28, 2015
2cc2860
Merge pull request #1456 from AuxMon/master
stankovski Sep 28, 2015
e9cf24a
Merge pull request #75 from Azure/master
Sep 29, 2015
a7a4614
Merge pull request #76 from MabOneSdk/release
Sep 29, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[ShoeboxV2] MetricsDefinitionsOperations and MetricsOperations
  • Loading branch information
vcanaa committed Jul 23, 2015
commit 773fa549fe012dd4f5908804dbb1ec6f9088c2a8
268 changes: 268 additions & 0 deletions src/Insights/Customizations/LogOperations.Customization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
//
// Copyright (c) Microsoft. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Hyak.Common;
using Microsoft.Azure.Insights.Models;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;

namespace Microsoft.Azure.Insights
{
/// <summary>
/// Thick client class for getting logs
/// </summary>
internal partial class LogOperations
{
/// <summary>
/// Get logs.
/// </summary>
/// <param name="resourceUri">The resourceUri</param>
/// <param name="filterString">The filter string</param>
/// <param name="definitions">The log definitions</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns></returns>
public async Task<LogListResponse> GetLogsAsync(
string resourceUri,
string filterString,
IEnumerable<LogDefinition> definitions,
CancellationToken cancellationToken)
{
if (definitions == null)
{
throw new ArgumentNullException("definitions");
}

if (resourceUri == null)
{
throw new ArgumentNullException("resourceUri");
}

// Ensure exactly one '/' at the start
resourceUri = '/' + resourceUri.TrimStart('/');

LogListResponse result;
string invocationId = TracingAdapter.NextInvocationId.ToString(CultureInfo.InvariantCulture);

// If no definitions provided, return empty collection
if (!definitions.Any())
{
this.LogStartGetLogs(invocationId, resourceUri, filterString, definitions);
result = new LogListResponse()
{
RequestId = Guid.NewGuid().ToString("D"),
StatusCode = HttpStatusCode.OK,
LogCollection = new LogCollection()
{
Value = new Log[0]
}
};

this.LogEndGetLogs(invocationId, result);

return result;
}

// Parse LogFilter. Reusing the metric filter.
// We might consider extracting the parsing functionality to a class with a less specific name
MetricFilter filter = MetricFilterExpressionParser.Parse(filterString, false);

if (filter.StartTime == default(DateTime))
{
throw new InvalidOperationException("startTime is required");
}

if (filter.EndTime == default(DateTime))
{
throw new InvalidOperationException("endTime is required");
}

this.LogStartGetLogs(invocationId, resourceUri, filterString, definitions);

var logsPerBlob = new Dictionary<string, Task<Log>>(StringComparer.OrdinalIgnoreCase);

// We download all the relevant blobs first and then use the data later, to avoid download the same blob more than once.
foreach (LogDefinition logDefinition in definitions)
{
foreach (BlobInfo blobInfo in logDefinition.BlobLocation.BlobInfo)
{
if (blobInfo.EndTime < filter.StartTime || blobInfo.StartTime >= filter.EndTime)
{
continue;
}

string blobId = GetBlobEndpoint(blobInfo);
if (!logsPerBlob.ContainsKey(blobId))
{
logsPerBlob.Add(blobId, FetchLogFromBlob(blobInfo.BlobUri, filter, logDefinition.Category));
}
}
}

foreach (var task in logsPerBlob.Values)
{
await task;
}

var logsPerCategory = new Dictionary<string, Log>();
foreach (var task in logsPerBlob.Values)
{
Log log = task.Result;
Log existingLog;
if (logsPerCategory.TryGetValue(log.Category.Value, out existingLog))
{
((List<LogValue>)existingLog.Value).AddRange(log.Value);
existingLog.StartTime = this.Min(log.StartTime, existingLog.StartTime);
existingLog.EndTime = this.Max(log.StartTime, existingLog.StartTime);
}
else
{
logsPerCategory.Add(log.Category.Value, log);
}
}

result = new LogListResponse
{
RequestId = Guid.NewGuid().ToString("D"),
StatusCode = HttpStatusCode.OK,
LogCollection = new LogCollection
{
Value = logsPerCategory.Values.ToList()
}
};

this.LogEndGetLogs(invocationId, result);

return result;
}

DateTime Max(DateTime a, DateTime b)
{
if (b.Ticks > a.Ticks)
{
return b;
}

return a;
}

DateTime Min(DateTime a, DateTime b)
{
if (b.Ticks < a.Ticks)
{
return b;
}

return a;
}

private static readonly char[] questionMark = { '?' };

private static string GetBlobEndpoint(BlobInfo blobInfo)
{
return blobInfo.BlobUri.Split(questionMark, StringSplitOptions.RemoveEmptyEntries)[0];
}

private async Task<Log> FetchLogFromBlob(string blobUri, MetricFilter filter, LocalizableString category)
{
var blob = new CloudBlockBlob(new Uri(blobUri));

using (var memoryStream = new MemoryStream())
{
try
{
await blob.DownloadToStreamAsync(memoryStream);
}
catch (StorageException ex)
{
if (ex.RequestInformation.HttpStatusCode == 404)
{
return new Log
{
Category = new LocalizableString
{
LocalizedValue = category.LocalizedValue,
Value = category.Value
},
StartTime = filter.StartTime,
EndTime = filter.EndTime,
Value = new List<LogValue>()
};
}

throw;
}

memoryStream.Seek(0, 0);
using (var streamReader = new StreamReader(memoryStream))
{
string content = await streamReader.ReadToEndAsync();
var logBlob = JsonConvert.DeserializeObject<LogBlob>(content);
var logValues = logBlob.records.Where(x => x.Time >= filter.StartTime && x.Time < filter.EndTime).ToList();

return new Log
{
Category = category,
StartTime = filter.StartTime,
EndTime = filter.EndTime,
Value = logValues
};
}
}
}

private class LogBlob
{
public List<LogValue> records { get; set; }
}

private void LogLogCountFromResponses(string invocationId, int logsCount)
{
if (TracingAdapter.IsEnabled)
{
TracingAdapter.Information("InvocationId: {0}. Total number of logs in all resposes: {1}", invocationId, logsCount);
}
}

private void LogEndGetLogs(string invocationId, LogListResponse result)
{
if (TracingAdapter.IsEnabled)
{
TracingAdapter.Exit(invocationId, result);
}
}

private void LogStartGetLogs(string invocationId, string resourceUri, string filterString, IEnumerable<LogDefinition> definitions)
{
if (TracingAdapter.IsEnabled)
{
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("resourceUri", resourceUri);
tracingParameters.Add("filterString", filterString);
tracingParameters.Add("definitions", string.Concat(definitions.Select(d => d.Category)));

TracingAdapter.Enter(invocationId, this, "GetLogsAsync", tracingParameters);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public async Task<MetricDefinitionListResponse> GetMetricDefinitionsAsync(string
{
this.Client.Cache[resourceUri] = definitions;
}

// wrap and return definitions
result = new MetricDefinitionListResponse()
{
Expand Down Expand Up @@ -122,7 +122,7 @@ private void LogStartGetMetricDefinitions(string invocationId, string resourceUr
tracingParameters.Add("resourceUri", resourceUri);
tracingParameters.Add("filterString", filterString);


TracingAdapter.Enter(invocationId, this, "GetMetricDefinitionsAsync", tracingParameters);
}
}
Expand Down
Loading