提交 2d0c254a 编写于 作者: G Gen Lu

Make it easier to query results from HistogramLogAggregator

上级 21c8f4d7
......@@ -15,6 +15,8 @@ internal sealed class CompletionProvidersLogger
private static readonly StatisticLogAggregator s_statisticLogAggregator = new StatisticLogAggregator();
private static readonly LogAggregator s_logAggregator = new LogAggregator();
private static readonly HistogramLogAggregator s_histogramLogAggregator = new HistogramLogAggregator(bucketSize: 50, maxBucketValue: 1000);
internal enum ActionInfo
{
TypeImportCompletionTicks,
......@@ -34,8 +36,11 @@ internal enum ActionInfo
ExtensionMethodCompletionMethodsChecked,
}
internal static void LogTypeImportCompletionTicksDataPoint(int count) =>
internal static void LogTypeImportCompletionTicksDataPoint(int count)
{
s_histogramLogAggregator.IncreaseCount((int)ActionInfo.TypeImportCompletionTicks, count);
s_statisticLogAggregator.AddDataPoint((int)ActionInfo.TypeImportCompletionTicks, count);
}
internal static void LogTypeImportCompletionItemCountDataPoint(int count) =>
s_statisticLogAggregator.AddDataPoint((int)ActionInfo.TypeImportCompletionItemCount, count);
......@@ -53,8 +58,11 @@ internal enum ActionInfo
internal static void LogExtensionMethodCompletionSuccess() =>
s_logAggregator.IncreaseCount((int)ActionInfo.ExtensionMethodCompletionSuccessCount);
internal static void LogExtensionMethodCompletionTicksDataPoint(int count) =>
internal static void LogExtensionMethodCompletionTicksDataPoint(int count)
{
s_histogramLogAggregator.IncreaseCount((int)ActionInfo.ExtensionMethodCompletionTicks, count);
s_statisticLogAggregator.AddDataPoint((int)ActionInfo.ExtensionMethodCompletionTicks, count);
}
internal static void LogExtensionMethodCompletionMethodsProvidedDataPoint(int count) =>
s_statisticLogAggregator.AddDataPoint((int)ActionInfo.ExtensionMethodCompletionMethodsProvided, count);
......@@ -93,6 +101,14 @@ internal static void ReportTelemetry()
var info = ((ActionInfo)kv.Key).ToString("f");
m[info] = kv.Value.GetCount();
}
foreach (var kv in s_histogramLogAggregator)
{
var info = ((ActionInfo)kv.Key).ToString("f");
m[$"{info}.BucketSize"] = kv.Value.BucketSize;
m[$"{info}.MaxBucketValue"] = kv.Value.MaxBucketValue;
m[$"{info}.Buckets"] = kv.Value.GetBucketsAsString();
}
}));
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.Internal.Log
{
/// <summary>
/// Defines a log aggregator to create a histogram
/// </summary>
internal class HistogramLogAggregator : AbstractLogAggregator<LogAggregator.Counter>
internal sealed class HistogramLogAggregator : AbstractLogAggregator<HistogramLogAggregator.HistogramCounter>
{
private readonly int _bucketSize;
private readonly int _maxBucketValue;
private readonly int _bucketCount;
public HistogramLogAggregator(int bucketSize, int maxBucketValue)
{
if (bucketSize <= 0 || maxBucketValue <= 0 || maxBucketValue % bucketSize != 0)
{
throw new ArgumentException();
}
_bucketSize = bucketSize;
_maxBucketValue = maxBucketValue;
_bucketCount = maxBucketValue / bucketSize + 1;
}
public void IncreaseCount(decimal value)
protected override HistogramCounter CreateCounter()
{
var counter = GetCounter(GetBucket(value));
counter.IncreaseCount();
return new HistogramCounter(_bucketSize, _maxBucketValue, _bucketCount);
}
public int GetCount(decimal value)
public void IncreaseCount(object key, decimal value)
{
if (TryGetCounter(GetBucket(value), out var counter))
{
return counter.GetCount();
}
return 0;
var counter = GetCounter(key);
counter.IncreaseCount(value);
}
protected override LogAggregator.Counter CreateCounter()
internal sealed class HistogramCounter
{
return new LogAggregator.Counter();
}
private readonly int[] _buckets;
private int GetBucket(decimal value)
{
var bucket = (int)Math.Floor(value / _bucketSize) * _bucketSize;
if (bucket > _maxBucketValue)
public int BucketCount { get; }
public int BucketSize { get; }
public int MaxBucketValue { get; }
public HistogramCounter(int bucketSize, int maxBucketValue, int bucketCount)
{
Debug.Assert(bucketSize > 0 && maxBucketValue > 0 && bucketCount > 0);
BucketSize = bucketSize;
MaxBucketValue = maxBucketValue;
BucketCount = bucketCount;
_buckets = new int[BucketCount];
}
public void IncreaseCount(decimal value)
{
bucket = _maxBucketValue;
var bucket = GetBucket(value);
_buckets[bucket]++;
}
return bucket;
public string GetBucketsAsString()
{
var pooledStringBuilder = PooledStringBuilder.GetInstance();
var builder = pooledStringBuilder.Builder;
builder.Append('[');
builder.Append(_buckets[0]);
for (var i = 1; i < _buckets.Length; ++i)
{
builder.Append(',');
builder.Append(_buckets[i]);
}
builder.Append(']');
return pooledStringBuilder.ToStringAndFree();
}
private int GetBucket(decimal value)
{
var bucket = (int)Math.Floor(value / BucketSize);
if (bucket >= BucketCount)
{
bucket = BucketCount - 1;
}
return bucket;
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.CodeAnalysis.Internal.Log
{
internal sealed class SyntacticLspLogger
{
private static readonly HistogramLogAggregator s_lexicalClassificationsLogAggregator = new HistogramLogAggregator(bucketSize: 100, maxBucketValue: 5000);
private static readonly HistogramLogAggregator s_syntacticClassificationsRemoteAggregator = new HistogramLogAggregator(bucketSize: 100, maxBucketValue: 5000);
private static readonly HistogramLogAggregator s_syntacticTaggerRemoteAggregator = new HistogramLogAggregator(bucketSize: 100, maxBucketValue: 5000);
private static readonly HistogramLogAggregator s_histogramLogAggregator = new HistogramLogAggregator(bucketSize: 100, maxBucketValue: 5000);
internal enum RequestType
{
......@@ -19,38 +15,40 @@ internal enum RequestType
internal static void LogRequestLatency(RequestType requestType, decimal latency)
{
switch (requestType)
{
case RequestType.LexicalClassifications:
s_lexicalClassificationsLogAggregator.IncreaseCount(latency);
break;
case RequestType.SyntacticClassifications:
s_syntacticClassificationsRemoteAggregator.IncreaseCount(latency);
break;
case RequestType.SyntacticTagger:
s_syntacticTaggerRemoteAggregator.IncreaseCount(latency);
break;
default:
break;
}
s_histogramLogAggregator.IncreaseCount(requestType, latency);
}
internal static void ReportTelemetry()
{
ReportTelemetry(FunctionId.Liveshare_LexicalClassifications, RequestType.LexicalClassifications.ToString(), s_lexicalClassificationsLogAggregator);
ReportTelemetry(FunctionId.Liveshare_SyntacticClassifications, RequestType.SyntacticClassifications.ToString(), s_syntacticClassificationsRemoteAggregator);
ReportTelemetry(FunctionId.Liveshare_SyntacticTagger, RequestType.SyntacticTagger.ToString(), s_syntacticTaggerRemoteAggregator);
static void ReportTelemetry(FunctionId functionId, string typeName, HistogramLogAggregator aggregator)
foreach (var kv in s_histogramLogAggregator)
{
Report((RequestType)kv.Key, kv.Value);
}
static void Report(RequestType requestType, HistogramLogAggregator.HistogramCounter counter)
{
FunctionId functionId;
switch (requestType)
{
case RequestType.LexicalClassifications:
functionId = FunctionId.Liveshare_LexicalClassifications;
break;
case RequestType.SyntacticClassifications:
functionId = FunctionId.Liveshare_SyntacticClassifications;
break;
case RequestType.SyntacticTagger:
functionId = FunctionId.Liveshare_SyntacticTagger;
break;
default:
return;
}
Logger.Log(functionId, KeyValueLogMessage.Create(m =>
{
foreach (var kv in aggregator)
{
var info = $"{typeName}.{kv.Key}";
m[info] = kv.Value.GetCount();
}
m[$"{requestType.ToString()}.BucketSize"] = counter.BucketSize;
m[$"{requestType.ToString()}.MaxBucketValue"] = counter.MaxBucketValue;
m[$"{requestType.ToString()}.Buckets"] = counter.GetBucketsAsString();
}));
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册