Skip to content

Commit aa2de7a

Browse files
Reporters (#714)
1 parent 5f76f8b commit aa2de7a

17 files changed

+1084
-304
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.DevProxy.Abstractions;
5+
6+
public abstract class BaseReportingPlugin : BaseProxyPlugin
7+
{
8+
protected virtual void StoreReport(object report, ProxyEventArgsBase e)
9+
{
10+
if (report is null)
11+
{
12+
return;
13+
}
14+
15+
((Dictionary<string, object>)e.GlobalData[ProxyUtils.ReportsKey])[Name] = report;
16+
}
17+
}

dev-proxy-abstractions/ProxyUtils.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public static class ProxyUtils
3737
// doesn't end with a path separator
3838
public static string? AppFolder => Path.GetDirectoryName(AppContext.BaseDirectory);
3939

40+
public static readonly string ReportsKey = "Reports";
41+
4042
public static bool IsGraphRequest(Request request) => IsGraphUrl(request.RequestUri);
4143

4244
public static bool IsGraphUrl(Uri uri) =>

dev-proxy-plugins/MinimalPermissions/PermissionsType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Microsoft.DevProxy.Plugins.RequestLogs.MinimalPermissions;
22

3-
internal enum PermissionsType
3+
public enum PermissionsType
44
{
55
Application,
66
Delegated

dev-proxy-plugins/MinimalPermissions/RequestInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Microsoft.DevProxy.Plugins.RequestLogs.MinimalPermissions;
55

6-
internal class RequestInfo
6+
public class RequestInfo
77
{
88
[JsonPropertyName("requestUrl")]
99
public string Url { get; set; } = string.Empty;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.DevProxy.Abstractions;
5+
using Microsoft.Extensions.Configuration;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace Microsoft.DevProxy.Plugins.Reporters;
9+
10+
public abstract class BaseReporter : BaseProxyPlugin
11+
{
12+
public virtual string FileExtension => throw new NotImplementedException();
13+
14+
public override void Register(IPluginEvents pluginEvents,
15+
IProxyContext context,
16+
ISet<UrlToWatch> urlsToWatch,
17+
IConfigurationSection? configSection = null)
18+
{
19+
base.Register(pluginEvents, context, urlsToWatch, configSection);
20+
21+
pluginEvents.AfterRecordingStop += AfterRecordingStop;
22+
}
23+
24+
protected abstract string? GetReport(KeyValuePair<string, object> report);
25+
26+
protected virtual Task AfterRecordingStop(object sender, RecordingArgs e)
27+
{
28+
if (!e.GlobalData.ContainsKey(ProxyUtils.ReportsKey) ||
29+
e.GlobalData[ProxyUtils.ReportsKey] is not Dictionary<string, object> reports ||
30+
!reports.Any())
31+
{
32+
_logger?.LogDebug("No reports found");
33+
return Task.CompletedTask;
34+
}
35+
36+
foreach (var report in reports)
37+
{
38+
_logger?.LogDebug("Transforming report {reportKey}...", report.Key);
39+
40+
var reportContents = GetReport(report);
41+
42+
if (string.IsNullOrEmpty(reportContents))
43+
{
44+
_logger?.LogDebug("Report {reportKey} is empty, ignore", report.Key);
45+
continue;
46+
}
47+
48+
var fileName = $"{report.Key}_{Name}{FileExtension}";
49+
_logger?.LogDebug("File name for report {report}: {fileName}", report.Key, fileName);
50+
51+
if (File.Exists(fileName))
52+
{
53+
_logger?.LogDebug("File {fileName} already exists, appending timestamp", fileName);
54+
fileName = $"{report.Key}_{Name}_{DateTime.Now:yyyyMMddHHmmss}{FileExtension}";
55+
}
56+
57+
_logger?.LogDebug("Writing report {reportKey} to {fileName}...", report.Key, fileName);
58+
File.WriteAllText(fileName, reportContents);
59+
}
60+
61+
return Task.CompletedTask;
62+
}
63+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Text.Json;
5+
using Microsoft.DevProxy.Abstractions;
6+
using Microsoft.DevProxy.Plugins.RequestLogs;
7+
using Microsoft.Extensions.Logging;
8+
9+
namespace Microsoft.DevProxy.Plugins.Reporters;
10+
11+
public class JsonReporter : BaseReporter
12+
{
13+
public override string Name => nameof(JsonReporter);
14+
public override string FileExtension => ".json";
15+
16+
private readonly Dictionary<Type, Func<object, object>> _transformers = new()
17+
{
18+
{ typeof(ExecutionSummaryPluginReportByUrl), TransformExecutionSummary },
19+
{ typeof(ExecutionSummaryPluginReportByMessageType), TransformExecutionSummary },
20+
};
21+
22+
protected override string GetReport(KeyValuePair<string, object> report)
23+
{
24+
_logger?.LogDebug("Serializing report {reportKey}...", report.Key);
25+
26+
var reportData = report.Value;
27+
var reportType = reportData.GetType();
28+
29+
if (_transformers.TryGetValue(reportType, out var transform))
30+
{
31+
_logger?.LogDebug("Transforming {reportType} using {transform}...", reportType.Name, transform.Method.Name);
32+
reportData = transform(reportData);
33+
}
34+
else
35+
{
36+
_logger?.LogDebug("No transformer found for {reportType}", reportType.Name);
37+
}
38+
39+
if (reportData is string strVal)
40+
{
41+
_logger?.LogDebug("{reportKey} is a string. Checking if it's JSON...", report.Key);
42+
43+
try
44+
{
45+
JsonSerializer.Deserialize<object>(strVal);
46+
_logger?.LogDebug("{reportKey} is already JSON, ignore", report.Key);
47+
// already JSON, ignore
48+
return strVal;
49+
}
50+
catch
51+
{
52+
_logger?.LogDebug("{reportKey} is not JSON, serializing...", report.Key);
53+
}
54+
}
55+
56+
return JsonSerializer.Serialize(reportData, ProxyUtils.JsonSerializerOptions);
57+
}
58+
59+
private static object TransformExecutionSummary(object report)
60+
{
61+
var executionSummaryReport = (ExecutionSummaryPluginReportBase)report;
62+
return executionSummaryReport.Data;
63+
}
64+
}

0 commit comments

Comments
 (0)