override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { GameObject prefab = behaviour.GetPrefab(cell_type); DaedalusDebugUtils.Assert(prefab != null, "No variation was chosen for " + cell_type); GameObject go = (GameObject)GameObject.Instantiate(prefab, new Vector3(l.x * behaviour.tileSize, l.storey * (behaviour.wallHeight + behaviour.storeySeparationHeight), l.y * behaviour.tileSize), Quaternion.identity); go.name = cell_type.ToString(); if (orientation == VirtualMap.DirectionType.None) { orientation = VirtualMap.DirectionType.North; } switch (orientation) { case VirtualMap.DirectionType.West: go.transform.localEulerAngles = new Vector3(0, 180, 0); break; case VirtualMap.DirectionType.North: go.transform.localEulerAngles = new Vector3(0, 270, 0); break; case VirtualMap.DirectionType.East: go.transform.localEulerAngles = new Vector3(0, 0, 0); break; case VirtualMap.DirectionType.South: go.transform.localEulerAngles = new Vector3(0, 90, 0); break; } go.transform.localEulerAngles += new Vector3(0, 180, 0); // Orientation fix AddToMapGameObject(cell_type, go, cell_type == VirtualCell.CellType.Door, l.storey); }
// Calling this based on a grouping (in SasMetricRetriever) should guarantee that it will have metric names specified (cannot have empty group) internal override async Task<MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { if (filter == null) { throw new ArgumentNullException("filter"); } if (location == null) { throw new ArgumentNullException("location"); } // This is called based on the definitions no the dimension portion of the filter should never be null or empty if (filter.DimensionFilters == null || !filter.DimensionFilters.Any()) { throw new ArgumentNullException("filter.DimensionFilters"); } // Separate out capacity metrics and transaction metrics into two groups IEnumerable<string> capacityMetrics = filter.DimensionFilters.Select(df => df.Name).Where(StorageConstants.MetricNames.IsCapacityMetric); IEnumerable<string> transactionMetrics = filter.DimensionFilters.Select(df => df.Name).Where(n => !StorageConstants.MetricNames.IsCapacityMetric(n)); List<Task<IEnumerable<Metric>>> queryTasks = new List<Task<IEnumerable<Metric>>>(); // Add task to get capacity metrics (if any) if (capacityMetrics.Any()) { MetricTableInfo capacityTableInfo = location.TableInfo.FirstOrDefault(ti => StorageConstants.IsCapacityMetricsTable(ti.TableName)); if (capacityTableInfo == null) { throw new InvalidOperationException("Definitions for capacity metrics must contain table info for capacity metrics table"); } queryTasks.Add(GetCapacityMetricsAsync(filter, GetTableReference(location, capacityTableInfo), capacityMetrics, invocationId)); } // Add tasks to get transaction metrics (if any) if (transactionMetrics.Any()) { IEnumerable<MetricTableInfo> transactionTableInfos = location.TableInfo.Where(ti => !StorageConstants.IsCapacityMetricsTable(ti.TableName)); if (!transactionTableInfos.Any()) { throw new InvalidOperationException("Definitions for transaction metrics must contain table info for transaction metrics table"); } queryTasks.AddRange(transactionTableInfos .Select(info => GetTransactionMetricsAsync(filter, GetTableReference(location, info), transactionMetrics, invocationId))); } // Collect results and wrap return new MetricListResponse() { RequestId = invocationId, StatusCode = HttpStatusCode.OK, MetricCollection = new MetricCollection() { Value = (await CollectResultsAsync(queryTasks)).ToList() } }; }
private static IEnumerable <CloudTable> GetNdayTables(MetricFilter filter, MetricLocation location) { // Get the tables that overlap the timerange and create a table reference for each table return(location.TableInfo .Where(info => info.StartTime < filter.EndTime && info.EndTime > filter.StartTime) .Select(info => new CloudTableClient(new Uri(location.TableEndpoint), new StorageCredentials(info.SasToken)).GetTableReference(info.TableName))); }
override public MetricLocation GetWorldLocation(CellLocation l, int storey) { MetricLocation actual_location = this.virtual_maps[0].GetActualLocation(l, storey); actual_location.x *= 2; // Double, since a tilemap is two times as big actual_location.y *= 2; return(actual_location); }
private static void AreEqual(MetricLocation exp, MetricLocation act) { if (exp != null) { Assert.Equal(exp.PartitionKey, act.PartitionKey); Assert.Equal(exp.TableEndpoint, act.TableEndpoint); AreEqual(exp.TableInfo, act.TableInfo); } }
protected void BuildObject(VirtualMap map, CellLocation loc, int storey, VirtualCell.CellType type, VirtualMap.DirectionType dir) { if (type == VirtualCell.CellType.None || type == VirtualCell.CellType.EmptyPassage) { return; // TODO: Maybe this check should be in the physical map } // Debug.Log (loc + " " + type); MetricLocation metricLocation = GetWorldLocation(loc, storey); physical_map.CreateObject(map, metricLocation, type, dir); }
override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { GameObject go = null; if (alreadyCreated && currentIndex < spawnedSpriteGos.Count) { go = spawnedSpriteGos[currentIndex]; currentIndex++; } else { go = (GameObject)GameObject.Instantiate(behaviour.spritePrefab, new Vector3(l.x * behaviour.tileSize, 0, l.y * behaviour.tileSize), Quaternion.identity); spawnedSpriteGos.Add(go); } Sprite sprite = behaviour.GetPrefab(cell_type); go.GetComponent <SpriteRenderer>().sprite = sprite; go.name = cell_type.ToString(); go.GetComponent <BoxCollider2D>().size = new Vector2(behaviour.tileSize, behaviour.tileSize); AddToMapGameObject(cell_type, go); // Debug.Log ("Cell at " + l.x+"-"+l.y + " has orientation " + orientation); go.transform.localEulerAngles = new Vector3(90, 0, 0); switch (orientation) { case VirtualMap.DirectionType.West: go.transform.localEulerAngles = new Vector3(90, 0, 0); break; case VirtualMap.DirectionType.North: go.transform.localEulerAngles = new Vector3(90, 90, 0); break; case VirtualMap.DirectionType.East: go.transform.localEulerAngles = new Vector3(90, 180, 0); break; case VirtualMap.DirectionType.South: go.transform.localEulerAngles = new Vector3(90, 270, 0); break; } // Move walls up a bit if (VirtualCell.IsFloor(cell_type)) { // Already good } else { go.transform.localPosition += Vector3.up * 0.01f; } if (cell_type == VirtualCell.CellType.DoorHorizontalBottom) { go.transform.localPosition += Vector3.forward * behaviour.tileSize * 0.25f; } }
/// <summary> /// A string representation of the MetricLocation including indentation /// </summary> /// <param name="metricLocation">The MetricLocation object</param> /// <param name="indentationTabs">The number of tabs to insert in front of each member</param> /// <returns>A string representation of the MetricLocation including indentation</returns> public static string ToString(this MetricLocation metricLocation, int indentationTabs) { StringBuilder output = new StringBuilder(); if (metricLocation != null) { output.AppendLine(); output.AddSpacesInFront(indentationTabs).AppendLine("Table endpoint : " + metricLocation.TableEndpoint); output.AddSpacesInFront(indentationTabs).AppendLine("Table info : " + metricLocation.TableInfo); output.AddSpacesInFront(indentationTabs).Append("PartitionKey : " + metricLocation.PartitionKey); } return(output.ToString()); }
override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { Texture2D tile_texture = null; tile_texture = behaviour.GetPrefab(cell_type); GameObject go = (GameObject)GameObject.Instantiate(behaviour.tilePrefab, new Vector3(l.x * behaviour.tileSize, 0, l.y * behaviour.tileSize), Quaternion.identity); var tempMaterial = new Material(go.transform.GetComponent <Renderer>().sharedMaterial); tempMaterial.SetTexture("_MainTex", tile_texture); tempMaterial.name = cell_type.ToString() + "_Material"; go.transform.GetComponent <Renderer>().sharedMaterial = tempMaterial; if (createdMaterialsList == null) { createdMaterialsList = new List <Material>(); } createdMaterialsList.Add(tempMaterial); go.name = cell_type.ToString(); AddToMapGameObject(cell_type, go); go.transform.localEulerAngles = new Vector3(0, 0, 0); switch (orientation) { case VirtualMap.DirectionType.West: go.transform.localEulerAngles = new Vector3(0, 0, 0); break; case VirtualMap.DirectionType.North: go.transform.localEulerAngles = new Vector3(0, 90, 0); break; case VirtualMap.DirectionType.East: go.transform.localEulerAngles = new Vector3(0, 180, 0); break; case VirtualMap.DirectionType.South: go.transform.localEulerAngles = new Vector3(0, 270, 0); break; } // Move walls up a bit if (VirtualCell.IsFloor(cell_type)) { // Already good } else { go.transform.localPosition += Vector3.up * 0.01f; } }
// Fixed orientation! override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { if (cell_type != VirtualCell.CellType.CorridorFloor) { Debug.Log("Bobor!"); } GameObject prefab = behaviour.GetPrefab(cell_type, orientation); // NOTE THE ORIENTATION HERE TOO! DaedalusDebugUtils.Assert(prefab != null, "No variation was chosen for " + cell_type); GameObject go = (GameObject)GameObject.Instantiate(prefab, new Vector3(l.x * behaviour.tileSize, l.storey * (behaviour.wallHeight + behaviour.storeySeparationHeight), l.y * behaviour.tileSize), Quaternion.identity); go.name = cell_type.ToString() + "_" + orientation.ToString(); go.transform.localEulerAngles += new Vector3(0, 90, 0); // Orientation fix AddToMapGameObject(cell_type, go, cell_type == VirtualCell.CellType.Door, l.storey); }
override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { GameObject prefab = behaviour.GetPrefab(cell_type); DaedalusDebugUtils.Assert(prefab != null, "No variation was chosen for " + cell_type); // Debug.Log (cell_type); GameObject go = (GameObject)GameObject.Instantiate(prefab, new Vector3(l.x * behaviour.tileSize, l.storey * (behaviour.wallHeight + behaviour.storeySeparationHeight), l.y * behaviour.tileSize), Quaternion.identity); go.name = cell_type.ToString(); switch (orientation) { case VirtualMap.DirectionType.West: go.transform.localEulerAngles = new Vector3(0, 180, 0); break; case VirtualMap.DirectionType.North: go.transform.localEulerAngles = new Vector3(0, 270, 0); break; case VirtualMap.DirectionType.East: break; case VirtualMap.DirectionType.South: go.transform.localEulerAngles = new Vector3(0, 90, 0); break; } // Checking orientation and position for ceiling if (cell_type == VirtualCell.CellType.CorridorCeiling || cell_type == VirtualCell.CellType.RoomCeiling) { Vector3 tmpPos = go.transform.position; tmpPos.y += behaviour.wallHeight; go.transform.position = tmpPos; Vector3 tmpRot = go.transform.localEulerAngles; tmpRot.x = 180; go.transform.localEulerAngles = tmpRot; } bool isDynamicCell = GetIsDynamicCell(cell_type); AddToMapGameObject(cell_type, go, isDynamicCell, l.storey); }
override public void CreateObject(VirtualMap map, MetricLocation l, VirtualCell.CellType cell_type, VirtualMap.DirectionType orientation) { GameObject prefab = behaviour.GetPrefab(cell_type); DaedalusDebugUtils.Assert(prefab != null, "No variation was chosen for " + cell_type); GameObject go = (GameObject)GameObject.Instantiate(prefab, new Vector3(l.x * behaviour.tileSize, 0, l.y * behaviour.tileSize), Quaternion.identity); go.name = cell_type.ToString(); if (orientation == VirtualMap.DirectionType.None) { orientation = VirtualMap.DirectionType.North; } switch (orientation) { case VirtualMap.DirectionType.West: go.transform.localEulerAngles = new Vector3(90, 0, 0); break; case VirtualMap.DirectionType.North: go.transform.localEulerAngles = new Vector3(90, 90, 0); break; case VirtualMap.DirectionType.East: go.transform.localEulerAngles = new Vector3(90, 180, 0); break; case VirtualMap.DirectionType.South: go.transform.localEulerAngles = new Vector3(90, 270, 0); break; } AddToMapGameObject(cell_type, go, cell_type == VirtualCell.CellType.Door, l.storey); // Move walls up a bit if (VirtualCell.IsFloor(cell_type)) { // Already good } else { go.transform.localPosition += Vector3.up * 0.01f; } }
/// <summary> /// The List Metric Definitions operation lists the metric definitions /// for the resource. /// </summary> /// <param name='resourceUri'> /// Required. The resource identifier of the target resource to get /// metrics for. /// </param> /// <param name='filterString'> /// Optional. An OData $filter expression that supports querying by the /// name of the metric definition. For example, "name.value eq /// 'Percentage CPU'". Name is optional, meaning the expression may be /// "". /// </param> /// <param name='cancellationToken'> /// Cancellation token. /// </param> /// <returns> /// The List Metric Definitions operation response. /// </returns> public async Task <MetricDefinitionListResponse> GetMetricDefinitionsAsync(string resourceUri, string filterString, CancellationToken cancellationToken) { // Validate if (resourceUri == null) { throw new ArgumentNullException("resourceUri"); } // Tracing bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = Tracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("resourceUri", resourceUri); tracingParameters.Add("filterString", filterString); Tracing.Enter(invocationId, this, "GetMetricDefinitionsAsync", tracingParameters); } // Construct URL string url = "/" + resourceUri.Trim() + "/metricDefinitions?"; url = url + "api-version=2014-04-01"; if (filterString != null) { url = url + "&$filter=" + Uri.EscapeDataString(filterString != null ? filterString.Trim() : ""); } string baseUrl = this.Client.BaseUri.AbsoluteUri; // Trim '/' character from the end of baseUrl and beginning of url. if (baseUrl[baseUrl.Length - 1] == '/') { baseUrl = baseUrl.Substring(0, baseUrl.Length - 1); } if (url[0] == '/') { url = url.Substring(1); } url = baseUrl + "/" + url; url = url.Replace(" ", "%20"); // Create HTTP transport objects HttpRequestMessage httpRequest = null; try { httpRequest = new HttpRequestMessage(); httpRequest.Method = HttpMethod.Get; httpRequest.RequestUri = new Uri(url); // Set Headers httpRequest.Headers.Add("Accept", "application/json"); httpRequest.Headers.Add("x-ms-version", "2014-04-01"); // Set Credentials cancellationToken.ThrowIfCancellationRequested(); await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); // Send Request HttpResponseMessage httpResponse = null; try { if (shouldTrace) { Tracing.SendRequest(invocationId, httpRequest); } cancellationToken.ThrowIfCancellationRequested(); httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { Tracing.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode statusCode = httpResponse.StatusCode; if (statusCode != HttpStatusCode.OK) { cancellationToken.ThrowIfCancellationRequested(); CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false)); if (shouldTrace) { Tracing.Error(invocationId, ex); } throw ex; } // Create Result MetricDefinitionListResponse result = null; // Deserialize Response cancellationToken.ThrowIfCancellationRequested(); string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); result = new MetricDefinitionListResponse(); JToken responseDoc = null; if (string.IsNullOrEmpty(responseContent) == false) { responseDoc = JToken.Parse(responseContent); } if (responseDoc != null && responseDoc.Type != JTokenType.Null) { MetricDefinitionCollection metricDefinitionCollectionInstance = new MetricDefinitionCollection(); result.MetricDefinitionCollection = metricDefinitionCollectionInstance; JToken valueArray = responseDoc["value"]; if (valueArray != null && valueArray.Type != JTokenType.Null) { foreach (JToken valueValue in ((JArray)valueArray)) { MetricDefinition metricDefinitionInstance = new MetricDefinition(); metricDefinitionCollectionInstance.Value.Add(metricDefinitionInstance); JToken nameValue = valueValue["name"]; if (nameValue != null && nameValue.Type != JTokenType.Null) { LocalizableString nameInstance = new LocalizableString(); metricDefinitionInstance.Name = nameInstance; JToken valueValue2 = nameValue["value"]; if (valueValue2 != null && valueValue2.Type != JTokenType.Null) { string valueInstance = ((string)valueValue2); nameInstance.Value = valueInstance; } JToken localizedValueValue = nameValue["localizedValue"]; if (localizedValueValue != null && localizedValueValue.Type != JTokenType.Null) { string localizedValueInstance = ((string)localizedValueValue); nameInstance.LocalizedValue = localizedValueInstance; } } JToken unitValue = valueValue["unit"]; if (unitValue != null && unitValue.Type != JTokenType.Null) { Unit unitInstance = ((Unit)Enum.Parse(typeof(Unit), ((string)unitValue), true)); metricDefinitionInstance.Unit = unitInstance; } JToken primaryAggregationTypeValue = valueValue["primaryAggregationType"]; if (primaryAggregationTypeValue != null && primaryAggregationTypeValue.Type != JTokenType.Null) { AggregationType primaryAggregationTypeInstance = ((AggregationType)Enum.Parse(typeof(AggregationType), ((string)primaryAggregationTypeValue), true)); metricDefinitionInstance.PrimaryAggregationType = primaryAggregationTypeInstance; } JToken resourceUriValue = valueValue["resourceUri"]; if (resourceUriValue != null && resourceUriValue.Type != JTokenType.Null) { string resourceUriInstance = ((string)resourceUriValue); metricDefinitionInstance.ResourceUri = resourceUriInstance; } JToken metricAvailabilitiesArray = valueValue["metricAvailabilities"]; if (metricAvailabilitiesArray != null && metricAvailabilitiesArray.Type != JTokenType.Null) { foreach (JToken metricAvailabilitiesValue in ((JArray)metricAvailabilitiesArray)) { MetricAvailability metricAvailabilityInstance = new MetricAvailability(); metricDefinitionInstance.MetricAvailabilities.Add(metricAvailabilityInstance); JToken timeGrainValue = metricAvailabilitiesValue["timeGrain"]; if (timeGrainValue != null && timeGrainValue.Type != JTokenType.Null) { TimeSpan timeGrainInstance = TypeConversion.From8601TimeSpan(((string)timeGrainValue)); metricAvailabilityInstance.TimeGrain = timeGrainInstance; } JToken retentionValue = metricAvailabilitiesValue["retention"]; if (retentionValue != null && retentionValue.Type != JTokenType.Null) { TimeSpan retentionInstance = TypeConversion.From8601TimeSpan(((string)retentionValue)); metricAvailabilityInstance.Retention = retentionInstance; } JToken locationValue = metricAvailabilitiesValue["location"]; if (locationValue != null && locationValue.Type != JTokenType.Null) { MetricLocation locationInstance = new MetricLocation(); metricAvailabilityInstance.Location = locationInstance; JToken tableEndpointValue = locationValue["tableEndpoint"]; if (tableEndpointValue != null && tableEndpointValue.Type != JTokenType.Null) { string tableEndpointInstance = ((string)tableEndpointValue); locationInstance.TableEndpoint = tableEndpointInstance; } JToken tableInfoArray = locationValue["tableInfo"]; if (tableInfoArray != null && tableInfoArray.Type != JTokenType.Null) { foreach (JToken tableInfoValue in ((JArray)tableInfoArray)) { MetricTableInfo metricTableInfoInstance = new MetricTableInfo(); locationInstance.TableInfo.Add(metricTableInfoInstance); JToken tableNameValue = tableInfoValue["tableName"]; if (tableNameValue != null && tableNameValue.Type != JTokenType.Null) { string tableNameInstance = ((string)tableNameValue); metricTableInfoInstance.TableName = tableNameInstance; } JToken startTimeValue = tableInfoValue["startTime"]; if (startTimeValue != null && startTimeValue.Type != JTokenType.Null) { DateTime startTimeInstance = ((DateTime)startTimeValue); metricTableInfoInstance.StartTime = startTimeInstance; } JToken endTimeValue = tableInfoValue["endTime"]; if (endTimeValue != null && endTimeValue.Type != JTokenType.Null) { DateTime endTimeInstance = ((DateTime)endTimeValue); metricTableInfoInstance.EndTime = endTimeInstance; } JToken sasTokenValue = tableInfoValue["sasToken"]; if (sasTokenValue != null && sasTokenValue.Type != JTokenType.Null) { string sasTokenInstance = ((string)sasTokenValue); metricTableInfoInstance.SasToken = sasTokenInstance; } JToken sasTokenExpirationTimeValue = tableInfoValue["sasTokenExpirationTime"]; if (sasTokenExpirationTimeValue != null && sasTokenExpirationTimeValue.Type != JTokenType.Null) { DateTime sasTokenExpirationTimeInstance = ((DateTime)sasTokenExpirationTimeValue); metricTableInfoInstance.SasTokenExpirationTime = sasTokenExpirationTimeInstance; } } } JToken partitionKeyValue = locationValue["partitionKey"]; if (partitionKeyValue != null && partitionKeyValue.Type != JTokenType.Null) { string partitionKeyInstance = ((string)partitionKeyValue); locationInstance.PartitionKey = partitionKeyInstance; } } } } JToken propertiesSequenceElement = ((JToken)valueValue["properties"]); if (propertiesSequenceElement != null && propertiesSequenceElement.Type != JTokenType.Null) { foreach (JProperty property in propertiesSequenceElement) { string propertiesKey = ((string)property.Name); string propertiesValue = ((string)property.Value); metricDefinitionInstance.Properties.Add(propertiesKey, propertiesValue); } } } } } result.StatusCode = statusCode; if (httpResponse.Headers.Contains("x-ms-request-id")) { result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault(); } if (shouldTrace) { Tracing.Exit(invocationId, result); } return(result); } finally { if (httpResponse != null) { httpResponse.Dispose(); } } } finally { if (httpRequest != null) { httpRequest.Dispose(); } } }
/// <summary> /// Retrieves the metric values from the shoebox /// </summary> /// <param name="filter">The $filter query string</param> /// <param name="location">The MetricLocation object</param> /// <param name="invocationId">The invocation id</param> /// <returns>The MetricValueListResponse</returns> // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) internal MetricListResponse GetMetricsInternal(MetricFilter filter, MetricLocation location, string invocationId) { return(GetMetricsInternalAsync(filter, location, invocationId).Result); }
/// <summary> /// Retrieves the metric values from the shoebox /// </summary> /// <param name="filter">The $filter query string</param> /// <param name="location">The MetricLocation object</param> /// <param name="invocationId">The invocation id</param> /// <returns>The MetricValueListResponse</returns> // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) internal static async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { // If metrics are requested by name, get those metrics specifically, unless too many are requested. // If no names or too many names are provided, get all metrics and filter if necessary. return(new MetricListResponse() { MetricCollection = await(filter.Names == null || filter.Names.Count() > MaxParallelRequestsByName ? GetMetricsByTimestampAsync(filter, location, invocationId) : GetMetricsByNameAsync(filter, location, invocationId)).ConfigureAwait(false) }); }
internal override async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { return(await ShoeboxClient.GetMetricsInternalAsync(filter, location, invocationId)); }
// Gets the named metric by calling the provided query on each table that overlaps the given time range // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) private static async Task <Metric> GetMetricAsync(string name, TableQuery query, MetricFilter filter, MetricLocation location, string invocationId) { // The GetEnititesAsync function provides one task that will call all the queries in parallel return(new Metric() { Name = new LocalizableString() { Value = name }, StartTime = filter.StartTime, EndTime = filter.EndTime, TimeGrain = filter.TimeGrain, MetricValues = (await GetEntitiesAsync(GetNdayTables(filter, location), query, invocationId).ConfigureAwait(false)).Select(ResolveMetricEntity).ToList() }); }
private static CloudTable GetTableReference(MetricLocation location, MetricTableInfo tableInfo) { return new CloudTableClient(new Uri(location.TableEndpoint), new StorageCredentials(tableInfo.SasToken)).GetTableReference(tableInfo.TableName); }
// Calling this based on a grouping (in SasMetricRetriever) should guarantee that it will have metric names specified (cannot have empty group) internal override async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { if (filter == null) { throw new ArgumentNullException("filter"); } if (location == null) { throw new ArgumentNullException("location"); } // This is called based on the definitions no the dimension portion of the filter should never be null or empty if (filter.DimensionFilters == null || !filter.DimensionFilters.Any()) { throw new ArgumentNullException("filter.DimensionFilters"); } // Separate out capacity metrics and transaction metrics into two groups IEnumerable <string> capacityMetrics = filter.DimensionFilters.Select(df => df.Name).Where(StorageConstants.MetricNames.IsCapacityMetric); IEnumerable <string> transactionMetrics = filter.DimensionFilters.Select(df => df.Name).Where(n => !StorageConstants.MetricNames.IsCapacityMetric(n)); List <Task <IEnumerable <Metric> > > queryTasks = new List <Task <IEnumerable <Metric> > >(); // Add task to get capacity metrics (if any) if (capacityMetrics.Any()) { MetricTableInfo capacityTableInfo = location.TableInfo.FirstOrDefault(ti => StorageConstants.IsCapacityMetricsTable(ti.TableName)); if (capacityTableInfo == null) { throw new InvalidOperationException("Definitions for capacity metrics must contain table info for capacity metrics table"); } queryTasks.Add(GetCapacityMetricsAsync(filter, GetTableReference(location, capacityTableInfo), capacityMetrics, invocationId)); } // Add tasks to get transaction metrics (if any) if (transactionMetrics.Any()) { IEnumerable <MetricTableInfo> transactionTableInfos = location.TableInfo.Where(ti => !StorageConstants.IsCapacityMetricsTable(ti.TableName)); if (!transactionTableInfos.Any()) { throw new InvalidOperationException("Definitions for transaction metrics must contain table info for transaction metrics table"); } queryTasks.AddRange(transactionTableInfos .Select(info => GetTransactionMetricsAsync(filter, GetTableReference(location, info), transactionMetrics, invocationId))); } // Collect results and wrap return(new MetricListResponse() { RequestId = invocationId, StatusCode = HttpStatusCode.OK, MetricCollection = new MetricCollection() { Value = (await CollectResultsAsync(queryTasks)).ToList() } }); }
private static CloudTable GetTableReference(MetricLocation location, MetricTableInfo tableInfo) { return(new CloudTableClient(new Uri(location.TableEndpoint), new StorageCredentials(tableInfo.SasToken)).GetTableReference(tableInfo.TableName)); }
/// <summary> /// The List Metric Definitions operation lists the metric definitions /// for the resource. /// </summary> /// <param name='resourceUri'> /// Required. The resource identifier of the target resource to get /// metrics for. /// </param> /// <param name='filterString'> /// Optional. An OData $filter expression that supports querying by the /// name of the metric definition. For example, "name.value eq /// 'Percentage CPU'". Name is optional, meaning the expression may be /// "". /// </param> /// <param name='cancellationToken'> /// Cancellation token. /// </param> /// <returns> /// The List Metric Definitions operation response. /// </returns> internal async Task <MetricDefinitionListResponse> GetMetricDefinitionsInternalAsync(string resourceUri, string filterString, CancellationToken cancellationToken) { // Validate if (resourceUri == null) { throw new ArgumentNullException("resourceUri"); } // Tracing bool shouldTrace = TracingAdapter.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = TracingAdapter.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("resourceUri", resourceUri); tracingParameters.Add("filterString", filterString); TracingAdapter.Enter(invocationId, this, "GetMetricDefinitionsAsync", tracingParameters); } #region Manually added // We need to handle document db differently for now until they onboard to shoebox. // Construct URL string url = ""; url = url + "/"; url = url + resourceUri; List <string> queryParameters = new List <string>(); if (Util.IsLegacyResource(resourceUri)) { url = url + "/metricDefinitions"; queryParameters.Add("api-version=2014-04-01"); } else { url = url + "/providers/microsoft.insights/metricDefinitions"; queryParameters.Add("api-version=2015-07-01"); } #endregion List <string> odataFilter = new List <string>(); if (filterString != null) { odataFilter.Add(Uri.EscapeDataString(filterString)); } if (odataFilter.Count > 0) { queryParameters.Add("$filter=" + string.Join(null, odataFilter)); } if (queryParameters.Count > 0) { url = url + "?" + string.Join("&", queryParameters); } string baseUrl = this.Client.BaseUri.AbsoluteUri; // Trim '/' character from the end of baseUrl and beginning of url. if (baseUrl[baseUrl.Length - 1] == '/') { baseUrl = baseUrl.Substring(0, baseUrl.Length - 1); } if (url[0] == '/') { url = url.Substring(1); } url = baseUrl + "/" + url; url = url.Replace(" ", "%20"); // Create HTTP transport objects HttpRequestMessage httpRequest = null; try { httpRequest = new HttpRequestMessage(); httpRequest.Method = HttpMethod.Get; httpRequest.RequestUri = new Uri(url); // Set Headers httpRequest.Headers.Add("Accept", "application/json"); httpRequest.Headers.Add("x-ms-version", "2014-04-01"); // Set Credentials cancellationToken.ThrowIfCancellationRequested(); await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); // Send Request HttpResponseMessage httpResponse = null; try { if (shouldTrace) { TracingAdapter.SendRequest(invocationId, httpRequest); } cancellationToken.ThrowIfCancellationRequested(); httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { TracingAdapter.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode statusCode = httpResponse.StatusCode; if (statusCode != HttpStatusCode.OK) { cancellationToken.ThrowIfCancellationRequested(); CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false)); if (shouldTrace) { TracingAdapter.Error(invocationId, ex); } throw ex; } // Create Result MetricDefinitionListResponse result = null; // Deserialize Response if (statusCode == HttpStatusCode.OK) { cancellationToken.ThrowIfCancellationRequested(); string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); result = new MetricDefinitionListResponse(); JToken responseDoc = null; if (string.IsNullOrEmpty(responseContent) == false) { responseDoc = JToken.Parse(responseContent); } if (responseDoc != null && responseDoc.Type != JTokenType.Null) { MetricDefinitionCollection metricDefinitionCollectionInstance = new MetricDefinitionCollection(); result.MetricDefinitionCollection = metricDefinitionCollectionInstance; JToken valueArray = responseDoc["value"]; if (valueArray != null && valueArray.Type != JTokenType.Null) { foreach (JToken valueValue in ((JArray)valueArray)) { MetricDefinition metricDefinitionInstance = new MetricDefinition(); metricDefinitionCollectionInstance.Value.Add(metricDefinitionInstance); JToken nameValue = valueValue["name"]; if (nameValue != null && nameValue.Type != JTokenType.Null) { LocalizableString nameInstance = new LocalizableString(); metricDefinitionInstance.Name = nameInstance; JToken valueValue2 = nameValue["value"]; if (valueValue2 != null && valueValue2.Type != JTokenType.Null) { string valueInstance = ((string)valueValue2); nameInstance.Value = valueInstance; } JToken localizedValueValue = nameValue["localizedValue"]; if (localizedValueValue != null && localizedValueValue.Type != JTokenType.Null) { string localizedValueInstance = ((string)localizedValueValue); nameInstance.LocalizedValue = localizedValueInstance; } } JToken unitValue = valueValue["unit"]; if (unitValue != null && unitValue.Type != JTokenType.Null) { Unit unitInstance = ((Unit)Enum.Parse(typeof(Unit), ((string)unitValue), true)); metricDefinitionInstance.Unit = unitInstance; } JToken primaryAggregationTypeValue = valueValue["primaryAggregationType"]; if (primaryAggregationTypeValue != null && primaryAggregationTypeValue.Type != JTokenType.Null) { AggregationType primaryAggregationTypeInstance = ((AggregationType)Enum.Parse(typeof(AggregationType), ((string)primaryAggregationTypeValue), true)); metricDefinitionInstance.PrimaryAggregationType = primaryAggregationTypeInstance; } JToken resourceUriValue = valueValue["resourceUri"]; if (resourceUriValue != null && resourceUriValue.Type != JTokenType.Null) { string resourceUriInstance = ((string)resourceUriValue); metricDefinitionInstance.ResourceId = resourceUriInstance; } JToken metricAvailabilitiesArray = valueValue["metricAvailabilities"]; if (metricAvailabilitiesArray != null && metricAvailabilitiesArray.Type != JTokenType.Null) { foreach (JToken metricAvailabilitiesValue in ((JArray)metricAvailabilitiesArray)) { MetricAvailability metricAvailabilityInstance = new MetricAvailability(); metricDefinitionInstance.MetricAvailabilities.Add(metricAvailabilityInstance); JToken timeGrainValue = metricAvailabilitiesValue["timeGrain"]; if (timeGrainValue != null && timeGrainValue.Type != JTokenType.Null) { TimeSpan timeGrainInstance = XmlConvert.ToTimeSpan(((string)timeGrainValue)); metricAvailabilityInstance.TimeGrain = timeGrainInstance; } JToken retentionValue = metricAvailabilitiesValue["retention"]; if (retentionValue != null && retentionValue.Type != JTokenType.Null) { TimeSpan retentionInstance = XmlConvert.ToTimeSpan(((string)retentionValue)); metricAvailabilityInstance.Retention = retentionInstance; } JToken locationValue = metricAvailabilitiesValue["location"]; if (locationValue != null && locationValue.Type != JTokenType.Null) { MetricLocation locationInstance = new MetricLocation(); metricAvailabilityInstance.Location = locationInstance; JToken tableEndpointValue = locationValue["tableEndpoint"]; if (tableEndpointValue != null && tableEndpointValue.Type != JTokenType.Null) { string tableEndpointInstance = ((string)tableEndpointValue); locationInstance.TableEndpoint = tableEndpointInstance; } JToken tableInfoArray = locationValue["tableInfo"]; if (tableInfoArray != null && tableInfoArray.Type != JTokenType.Null) { foreach (JToken tableInfoValue in ((JArray)tableInfoArray)) { MetricTableInfo metricTableInfoInstance = new MetricTableInfo(); locationInstance.TableInfo.Add(metricTableInfoInstance); JToken tableNameValue = tableInfoValue["tableName"]; if (tableNameValue != null && tableNameValue.Type != JTokenType.Null) { string tableNameInstance = ((string)tableNameValue); metricTableInfoInstance.TableName = tableNameInstance; } JToken startTimeValue = tableInfoValue["startTime"]; if (startTimeValue != null && startTimeValue.Type != JTokenType.Null) { DateTime startTimeInstance = ((DateTime)startTimeValue); metricTableInfoInstance.StartTime = startTimeInstance; } JToken endTimeValue = tableInfoValue["endTime"]; if (endTimeValue != null && endTimeValue.Type != JTokenType.Null) { DateTime endTimeInstance = ((DateTime)endTimeValue); metricTableInfoInstance.EndTime = endTimeInstance; } JToken sasTokenValue = tableInfoValue["sasToken"]; if (sasTokenValue != null && sasTokenValue.Type != JTokenType.Null) { string sasTokenInstance = ((string)sasTokenValue); metricTableInfoInstance.SasToken = sasTokenInstance; } JToken sasTokenExpirationTimeValue = tableInfoValue["sasTokenExpirationTime"]; if (sasTokenExpirationTimeValue != null && sasTokenExpirationTimeValue.Type != JTokenType.Null) { DateTime sasTokenExpirationTimeInstance = ((DateTime)sasTokenExpirationTimeValue); metricTableInfoInstance.SasTokenExpirationTime = sasTokenExpirationTimeInstance; } } } JToken partitionKeyValue = locationValue["partitionKey"]; if (partitionKeyValue != null && partitionKeyValue.Type != JTokenType.Null) { string partitionKeyInstance = ((string)partitionKeyValue); locationInstance.PartitionKey = partitionKeyInstance; } } JToken blobLocationValue = metricAvailabilitiesValue["blobLocation"]; if (blobLocationValue != null && blobLocationValue.Type != JTokenType.Null) { BlobLocation blobLocationInstance = new BlobLocation(); metricAvailabilityInstance.BlobLocation = blobLocationInstance; JToken blobEndpointValue = blobLocationValue["blobEndpoint"]; if (blobEndpointValue != null && blobEndpointValue.Type != JTokenType.Null) { string blobEndpointInstance = ((string)blobEndpointValue); blobLocationInstance.BlobEndpoint = blobEndpointInstance; } JToken blobInfoArray = blobLocationValue["blobInfo"]; if (blobInfoArray != null && blobInfoArray.Type != JTokenType.Null) { foreach (JToken blobInfoValue in ((JArray)blobInfoArray)) { BlobInfo blobInfoInstance = new BlobInfo(); blobLocationInstance.BlobInfo.Add(blobInfoInstance); JToken blobUriValue = blobInfoValue["blobUri"]; if (blobUriValue != null && blobUriValue.Type != JTokenType.Null) { string blobUriInstance = ((string)blobUriValue); blobInfoInstance.BlobUri = blobUriInstance; } JToken startTimeValue2 = blobInfoValue["startTime"]; if (startTimeValue2 != null && startTimeValue2.Type != JTokenType.Null) { DateTime startTimeInstance2 = ((DateTime)startTimeValue2); blobInfoInstance.StartTime = startTimeInstance2; } JToken endTimeValue2 = blobInfoValue["endTime"]; if (endTimeValue2 != null && endTimeValue2.Type != JTokenType.Null) { DateTime endTimeInstance2 = ((DateTime)endTimeValue2); blobInfoInstance.EndTime = endTimeInstance2; } JToken sasTokenValue2 = blobInfoValue["sasToken"]; if (sasTokenValue2 != null && sasTokenValue2.Type != JTokenType.Null) { string sasTokenInstance2 = ((string)sasTokenValue2); blobInfoInstance.SasToken = sasTokenInstance2; } } } } } } JToken propertiesSequenceElement = ((JToken)valueValue["properties"]); if (propertiesSequenceElement != null && propertiesSequenceElement.Type != JTokenType.Null) { foreach (JProperty property in propertiesSequenceElement) { string propertiesKey = ((string)property.Name); string propertiesValue = ((string)property.Value); metricDefinitionInstance.Properties.Add(propertiesKey, propertiesValue); } } JToken dimensionsArray = valueValue["dimensions"]; if (dimensionsArray != null && dimensionsArray.Type != JTokenType.Null) { foreach (JToken dimensionsValue in ((JArray)dimensionsArray)) { Dimension dimensionInstance = new Dimension(); metricDefinitionInstance.Dimensions.Add(dimensionInstance); JToken nameValue2 = dimensionsValue["name"]; if (nameValue2 != null && nameValue2.Type != JTokenType.Null) { LocalizableString nameInstance2 = new LocalizableString(); dimensionInstance.Name = nameInstance2; JToken valueValue3 = nameValue2["value"]; if (valueValue3 != null && valueValue3.Type != JTokenType.Null) { string valueInstance2 = ((string)valueValue3); nameInstance2.Value = valueInstance2; } JToken localizedValueValue2 = nameValue2["localizedValue"]; if (localizedValueValue2 != null && localizedValueValue2.Type != JTokenType.Null) { string localizedValueInstance2 = ((string)localizedValueValue2); nameInstance2.LocalizedValue = localizedValueInstance2; } } JToken valuesArray = dimensionsValue["values"]; if (valuesArray != null && valuesArray.Type != JTokenType.Null) { foreach (JToken valuesValue in ((JArray)valuesArray)) { LocalizableString localizableStringInstance = new LocalizableString(); dimensionInstance.Values.Add(localizableStringInstance); JToken valueValue4 = valuesValue["value"]; if (valueValue4 != null && valueValue4.Type != JTokenType.Null) { string valueInstance3 = ((string)valueValue4); localizableStringInstance.Value = valueInstance3; } JToken localizedValueValue3 = valuesValue["localizedValue"]; if (localizedValueValue3 != null && localizedValueValue3.Type != JTokenType.Null) { string localizedValueInstance3 = ((string)localizedValueValue3); localizableStringInstance.LocalizedValue = localizedValueInstance3; } } } } } } } } } result.StatusCode = statusCode; if (httpResponse.Headers.Contains("x-ms-request-id")) { result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault(); } if (shouldTrace) { TracingAdapter.Exit(invocationId, result); } return(result); } finally { if (httpResponse != null) { httpResponse.Dispose(); } } } finally { if (httpRequest != null) { httpRequest.Dispose(); } } }
// Generates queries for all metrics by timestamp (timestamp-name rowKey format) and filters the results to the requested metrics (if any) // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) private static async Task <MetricCollection> GetMetricsByTimestampAsync(MetricFilter filter, MetricLocation location, string invocationId) { // Find all the tables that fall partially or fully within the timerange IEnumerable <CloudTable> tables = GetNdayTables(filter, location); // Generate a query for the partition key and time range TableQuery query = GenerateMetricTimestampQuery(location.PartitionKey, filter.StartTime, filter.EndTime); // Get all the entities for the query IEnumerable <DynamicTableEntity> entities = await GetEntitiesAsync(tables, query, invocationId).ConfigureAwait(false); // Group entities by (encoded) name IEnumerable <IGrouping <string, DynamicTableEntity> > groups = entities.GroupBy(entity => entity.RowKey.Substring(entity.RowKey.LastIndexOf('_') + 1)); // if names are specified, filter the results to those metrics only if (filter.DimensionFilters != null) { groups = groups.Where(g => filter.DimensionFilters.Select(df => ShoeboxHelper.TrimAndEscapeKey(df.Name)).Contains(g.Key)); } // Construct MetricCollection (list of metrics) by taking each group and converting the entities in that group to MetricValue objects return(new MetricCollection() { Value = groups.Select(g => new Metric() { Name = new LocalizableString() { Value = FindMetricName(g.Key, filter.DimensionFilters.Select(df => df.Name)) }, StartTime = filter.StartTime, EndTime = filter.EndTime, TimeGrain = filter.TimeGrain, MetricValues = g.Select(ResolveMetricEntity).ToList() }).ToList() }); }
// Generates queries for each metric by name (name-timestamp rowKey format) at collects the results // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) private static async Task <MetricCollection> GetMetricsByNameAsync(MetricFilter filter, MetricLocation location, string invocationId) { // Create a query for each metric name Dictionary <string, TableQuery> queries = GenerateMetricNameQueries(filter.DimensionFilters.Select(df => df.Name), location.PartitionKey, filter.StartTime, filter.EndTime); // Create a task for each query. Each query will correspond to one metric IEnumerable <Task <Metric> > queryTasks = queries.Select(async kvp => await GetMetricByNameAsync(kvp.Key, kvp.Value, filter, location, invocationId).ConfigureAwait(false)); // Execute the queries in parallel and collect the results IList <Metric> metrics = await Task.Factory.ContinueWhenAll(queryTasks.ToArray(), tasks => new List <Metric>(tasks.Select(t => t.Result))).ConfigureAwait(false); // Wrap metrics in MetricCollectionObject return(new MetricCollection() { Value = metrics }); }
/// <summary> /// Retrieves the metric values from the shoebox /// </summary> /// <param name="filter">The $filter query string</param> /// <param name="location">The MetricLocation object</param> /// <param name="invocationId">The invocation id</param> /// <returns>The MetricValueListResponse</returns> // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) internal static async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { // TODO [davmc]: ShoeboxClient doesn't support dimensions if (filter.DimensionFilters != null && filter.DimensionFilters.Any(df => df.Dimensions != null)) { if (TracingAdapter.IsEnabled) { TracingAdapter.Information("InvocationId: {0}. ShoeboxClient encountered metrics with dimensions specified. These will be ignored.", invocationId); } // Remove dimensions from filter (The MetricFilter class has strict mutation rules used in parsing so the best way to modify it is to create a new one) filter = new MetricFilter() { TimeGrain = filter.TimeGrain, StartTime = filter.StartTime, EndTime = filter.EndTime, DimensionFilters = filter.DimensionFilters.Select(df => new MetricDimension() { Name = df.Name }) }; } // If metrics are requested by name, get those metrics specifically, unless too many are requested. // If no names or too many names are provided, get all metrics and filter if necessary. return(new MetricListResponse() { MetricCollection = await(filter.DimensionFilters == null || filter.DimensionFilters.Count() > MaxParallelRequestsByName ? GetMetricsByTimestampAsync(filter, location, invocationId) : GetMetricsByNameAsync(filter, location, invocationId)).ConfigureAwait(false) }); }
internal override async Task<MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { return await ShoeboxClient.GetMetricsInternalAsync(filter, location, invocationId); }
// Gets the named metric by calling the provided query on each table that overlaps the given time range // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) private static async Task <Metric> GetMetricByNameAsync(string name, TableQuery query, MetricFilter filter, MetricLocation location, string invocationId) { Metric metric = new Metric() { Name = new LocalizableString() { Value = name }, StartTime = filter.StartTime, EndTime = filter.EndTime, TimeGrain = filter.TimeGrain, MetricValues = new List <MetricValue>() }; var instanceMetrics = new List <MetricValue>(); var globalMetrics = new List <DynamicTableEntity>(); // The GetEnititesAsync function provides one task that will call all the queries in parallel var entities = await GetEntitiesAsync(GetNdayTables(filter, location), query, invocationId).ConfigureAwait(false); // Iterate over the instances to do conversion and aggregation when needed foreach (var entity in entities) { // Skip aggregated entities if (!IsInstanceMetric(entity.RowKey)) { // We ignore the aggergated metrics if there are instance metrics. if (instanceMetrics.Count == 0) { globalMetrics.Add(entity); } continue; } MetricValue lastMetricValue = instanceMetrics.LastOrDefault(); if (lastMetricValue == null) { instanceMetrics.Add(ResolveMetricEntity(entity)); } else { if (lastMetricValue.Timestamp.Ticks == GetTimestampFromIndexMetricNameTimestamp(entity)) { Aggregate(lastMetricValue, entity); } else { instanceMetrics.Add(ResolveMetricEntity(entity)); } } } if (instanceMetrics.Count > 0) { foreach (var metricValue in instanceMetrics) { metricValue.Average = metricValue.Total / metricValue.Count; } metric.MetricValues = instanceMetrics; } else { metric.MetricValues = globalMetrics.Select(me => ResolveMetricEntity(me)).ToList(); } return(metric); }
// Generates queries for all metrics by timestamp (timestamp-name rowKey format) and filters the results to the requested metrics (if any) // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) private static async Task <MetricCollection> GetMetricsByTimestampAsync(MetricFilter filter, MetricLocation location, string invocationId) { // Find all the tables that fall partially or fully within the timerange IEnumerable <CloudTable> tables = GetNdayTables(filter, location); // Generate a query for the partition key and time range TableQuery query = GenerateMetricTimestampQuery(location.PartitionKey, filter.StartTime, filter.EndTime); // Get all the entities for the query IEnumerable <DynamicTableEntity> entities = await GetEntitiesAsync(tables, query, invocationId).ConfigureAwait(false); ICollection <string> dimensionFilterNames = null; if (filter.DimensionFilters != null) { dimensionFilterNames = new HashSet <string>(filter.DimensionFilters.Select(df => ShoeboxHelper.TrimAndEscapeKey(df.Name))); } var metricWraps = new Dictionary <string, MetricWrap>(); var metrics = new List <Metric>(); // Iterate over the instances to do conversion and aggregation when needed. foreach (var entity in entities) { string encodedName = GetMetricNameFromRowKeyByTimestampByMetricName(entity.RowKey); // When there is filter, skip entities not included in the filter. if (dimensionFilterNames != null && !dimensionFilterNames.Contains(encodedName, StringComparer.OrdinalIgnoreCase)) { continue; } MetricWrap metricWrap; if (!metricWraps.TryGetValue(encodedName, out metricWrap)) { metricWrap = new MetricWrap { Metric = new Metric() { Name = new LocalizableString() { Value = encodedName }, StartTime = filter.StartTime, EndTime = filter.EndTime, TimeGrain = filter.TimeGrain, MetricValues = new List <MetricValue>() }, InstanceMetrics = new List <MetricValue>(), GlobalMetrics = new List <DynamicTableEntity>() }; metricWraps[encodedName] = metricWrap; metrics.Add(metricWrap.Metric); } // Skip aggregated entities if (!IsInstanceMetric(entity.RowKey)) { // We ignore the aggergated metrics if there are instance metrics. if (metricWrap.InstanceMetrics.Count == 0) { metricWrap.GlobalMetrics.Add(entity); } continue; } MetricValue lastMetricValue = metricWrap.InstanceMetrics.LastOrDefault(); if (lastMetricValue == null) { metricWrap.InstanceMetrics.Add(ResolveMetricEntity(entity)); } else { if (lastMetricValue.Timestamp.Ticks == GetTimestampFromIndexTimestampMetricName(entity)) { Aggregate(lastMetricValue, entity); } else { metricWrap.InstanceMetrics.Add(ResolveMetricEntity(entity)); } } } foreach (var metricWrap in metricWraps.Values) { // Decide whether to return the aggregation of the instance metrics on the fly or the final value in the storage account // If there are instance metrics, the aggregation on the fly is used. Metric metric = metricWrap.Metric; metric.Name.Value = FindMetricName(metric.Name.Value, dimensionFilterNames); if (metricWrap.InstanceMetrics.Count > 0) { foreach (var metricValue in metricWrap.InstanceMetrics) { metricValue.Average = metricValue.Total / metricValue.Count; } metric.MetricValues = metricWrap.InstanceMetrics; } else { metric.MetricValues = metricWrap.GlobalMetrics.Select(me => ResolveMetricEntity(me)).ToList(); } } return(new MetricCollection() { Value = metrics }); }
/// <summary> /// Retrieves the metric values from the shoebox /// </summary> /// <param name="filter">The $filter query string</param> /// <param name="location">The MetricLocation object</param> /// <param name="invocationId">The invocation id</param> /// <returns>The MetricValueListResponse</returns> // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) internal abstract Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId);
/// <summary> /// Retrieves the metric values from the shoebox /// </summary> /// <param name="filter">The $filter query string</param> /// <param name="location">The MetricLocation object</param> /// <param name="invocationId">The invocation id</param> /// <returns>The MetricValueListResponse</returns> // Note: Does not populate Metric fields unrelated to query (i.e. "display name", resourceUri, and properties) internal static async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId) { // TODO [davmc]: ShoeboxClient doesn't support dimensions if (filter.DimensionFilters != null && filter.DimensionFilters.Any(df => df.Dimensions != null)) { throw new ArgumentException("Shoebox client does not support dimensions", "filter"); } // If metrics are requested by name, get those metrics specifically, unless too many are requested. // If no names or too many names are provided, get all metrics and filter if necessary. return(new MetricListResponse() { MetricCollection = await(filter.DimensionFilters == null || filter.DimensionFilters.Count() > MaxParallelRequestsByName ? GetMetricsByTimestampAsync(filter, location, invocationId) : GetMetricsByNameAsync(filter, location, invocationId)).ConfigureAwait(false) }); }