Skip to content

Commit 84e1f7f

Browse files
authored
Merge pull request #124 from datalust/dev
2023.4.0 Release
2 parents 4658702 + d586359 commit 84e1f7f

File tree

10 files changed

+111
-27
lines changed

10 files changed

+111
-27
lines changed

src/Seq.Api/Client/SeqApiClient.cs

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public sealed class SeqApiClient : IDisposable
5959
/// <param name="serverUrl">The base URL of the Seq server.</param>
6060
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
6161
/// <param name="useDefaultCredentials">Whether default credentials will be sent with HTTP requests; the default is <c>true</c>.</param>
62-
[Obsolete("Prefer `SeqApiClient(serverUrl, apiKey, handler => handler.UseDefaultCredentials = true)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
62+
[Obsolete("Prefer `SeqApiClient(serverUrl, apiKey, createHttpMessageHandler)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
6363
public SeqApiClient(string serverUrl, string apiKey, bool useDefaultCredentials)
6464
: this(serverUrl, apiKey, handler => handler.UseDefaultCredentials = useDefaultCredentials)
6565
{
@@ -72,25 +72,45 @@ public SeqApiClient(string serverUrl, string apiKey, bool useDefaultCredentials)
7272
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
7373
/// <param name="configureHttpClientHandler">An optional callback to configure the <see cref="HttpClientHandler"/> used when making HTTP requests
7474
/// to the Seq API.</param>
75-
public SeqApiClient(string serverUrl, string apiKey = null, Action<HttpClientHandler> configureHttpClientHandler = null)
75+
[Obsolete("Prefer `SeqApiClient(serverUrl, apiKey, createHttpMessageHandler)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
76+
public SeqApiClient(string serverUrl, string apiKey, Action<HttpClientHandler> configureHttpClientHandler)
77+
: this(serverUrl, apiKey, cookies =>
78+
{
79+
var handler = new HttpClientHandler { CookieContainer = cookies };
80+
configureHttpClientHandler?.Invoke(handler);
81+
return handler;
82+
})
83+
{
84+
}
85+
86+
/// <summary>
87+
/// Construct a <see cref="SeqApiClient"/>.
88+
/// </summary>
89+
/// <param name="serverUrl">The base URL of the Seq server.</param>
90+
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
91+
/// <param name="createHttpMessageHandler">An optional callback to construct the HTTP message handler used when making requests
92+
/// to the Seq API. The callback receives a <see cref="CookieContainer"/> that is shared with WebSocket requests made by the client.</param>
93+
public SeqApiClient(string serverUrl, string apiKey = null, Func<CookieContainer, HttpMessageHandler> createHttpMessageHandler = null)
7694
{
95+
// This is required for compatibility with the obsolete constructor, which we can remove sometime in 2024.
96+
var httpMessageHandler = createHttpMessageHandler?.Invoke(_cookies) ??
97+
#if SOCKETS_HTTP_HANDLER
98+
new SocketsHttpHandler { CookieContainer = _cookies };
99+
#else
100+
new HttpClientHandler { CookieContainer = _cookies };
101+
#endif
102+
77103
ServerUrl = serverUrl ?? throw new ArgumentNullException(nameof(serverUrl));
78104

79105
if (!string.IsNullOrEmpty(apiKey))
80106
_apiKey = apiKey;
81-
82-
var handler = new HttpClientHandler
83-
{
84-
CookieContainer = _cookies
85-
};
86-
87-
configureHttpClientHandler?.Invoke(handler);
88-
107+
89108
var baseAddress = serverUrl;
90109
if (!baseAddress.EndsWith("/"))
91110
baseAddress += "/";
92111

93-
HttpClient = new HttpClient(handler) { BaseAddress = new Uri(baseAddress) };
112+
HttpClient = new HttpClient(httpMessageHandler);
113+
HttpClient.BaseAddress = new Uri(baseAddress);
94114
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(SeqApiV9MediaType));
95115

96116
if (_apiKey != null)
@@ -251,8 +271,8 @@ public async Task PutAsync<TEntity>(ILinked entity, string link, TEntity content
251271
var linkUri = ResolveLink(entity, link, parameters);
252272
var request = new HttpRequestMessage(HttpMethod.Put, linkUri) { Content = MakeJsonContent(content) };
253273
var stream = await HttpSendAsync(request, cancellationToken).ConfigureAwait(false);
254-
using (var reader = new StreamReader(stream))
255-
reader.ReadToEnd();
274+
using var reader = new StreamReader(stream);
275+
await reader.ReadToEndAsync();
256276
}
257277

258278
/// <summary>
@@ -270,8 +290,8 @@ public async Task DeleteAsync<TEntity>(ILinked entity, string link, TEntity cont
270290
var linkUri = ResolveLink(entity, link, parameters);
271291
var request = new HttpRequestMessage(HttpMethod.Delete, linkUri) { Content = MakeJsonContent(content) };
272292
var stream = await HttpSendAsync(request, cancellationToken).ConfigureAwait(false);
273-
using (var reader = new StreamReader(stream))
274-
reader.ReadToEnd();
293+
using var reader = new StreamReader(stream);
294+
await reader.ReadToEndAsync();
275295
}
276296

277297
/// <summary>
@@ -345,8 +365,8 @@ async Task<string> HttpGetStringAsync(string url, CancellationToken cancellation
345365
{
346366
var request = new HttpRequestMessage(HttpMethod.Get, url);
347367
var stream = await HttpSendAsync(request, cancellationToken).ConfigureAwait(false);
348-
using (var reader = new StreamReader(stream))
349-
return await reader.ReadToEndAsync();
368+
using var reader = new StreamReader(stream);
369+
return await reader.ReadToEndAsync().ConfigureAwait(false);
350370
}
351371

352372
async Task<Stream> HttpSendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default)

src/Seq.Api/Model/Alerting/AlertOccurrencePart.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class AlertOccurrencePart
1919
/// <summary>
2020
/// The time grouping that triggered the alert.
2121
/// </summary>
22-
public DateTimeRange DetectedOverRange { get; set; }
22+
public DateTimeRangePart DetectedOverRange { get; set; }
2323

2424
/// <summary>
2525
/// The level of notifications sent for this instance.

src/Seq.Api/Model/Alerting/AlertOccurrenceRangePart.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ public class AlertOccurrenceRangePart
1111
/// <summary>
1212
/// The time grouping that triggered the alert.
1313
/// </summary>
14-
public DateTimeRange DetectedOverRange { get; set; }
14+
public DateTimeRangePart DetectedOverRange { get; set; }
1515
}
1616
}

src/Seq.Api/Model/Cluster/ClusterNodeEntity.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ public class ClusterNodeEntity : Entity
4343
/// The time since the node's last completed sync operation.
4444
/// </summary>
4545
public double? MillisecondsSinceLastSync { get; set; }
46+
47+
/// <summary>
48+
/// The time since the follower's active sync was started.
49+
/// </summary>
50+
public double? MillisecondsSinceActiveSync { get; set; }
51+
52+
/// <summary>
53+
/// The total number of operations in the active sync.
54+
/// </summary>
55+
public int? TotalActiveOps { get; set; }
56+
57+
/// <summary>
58+
/// The remaining number of operations in the active sync.
59+
/// </summary>
60+
public int? RemainingActiveOps { get; set; }
4661

4762
/// <summary>
4863
/// An informational description of the node's current state, or <c langword="null">null</c> if no additional

src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ public class StorageConsumptionPart
2525
/// <summary>
2626
/// The range of timestamps covered by the result.
2727
/// </summary>
28-
public DateTimeRange Range { get; set; }
28+
public DateTimeRangePart Range { get; set; }
2929

3030
/// <summary>
3131
/// The available range of timestamps.
3232
/// </summary>
33-
public DateTimeRange FullRange { get; set; }
33+
public DateTimeRangePart FullRange { get; set; }
3434

3535
/// <summary>
3636
/// The duration of the timestamp interval covered by each result.

src/Seq.Api/Model/Events/EventEntity.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,24 @@ public class EventEntity : Entity
6262
/// </summary>
6363
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
6464
public string RenderedMessage { get; set; }
65+
66+
/// <summary>
67+
/// A trace id associated with the event, if any.
68+
/// </summary>
69+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
70+
public string TraceId { get; set; }
71+
72+
/// <summary>
73+
/// A span id associated with the event, if any.
74+
/// </summary>
75+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
76+
public string SpanId { get; set; }
77+
78+
/// <summary>
79+
/// A collection of properties describing the origin of the event, if any. These correspond to resource
80+
/// attributes in the OpenTelemetry spec.
81+
/// </summary>
82+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
83+
public List<EventPropertyPart> Resource { get; set; }
6584
}
6685
}

src/Seq.Api/Model/Shared/DateTimeRange.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Seq.Api.Model.Shared
55
/// <summary>
66
/// A range represented by a start and end <see cref="DateTime"/>.
77
/// </summary>
8-
public readonly struct DateTimeRange
8+
public readonly struct DateTimeRangePart
99
{
1010
/// <summary>
1111
/// The (inclusive) start of the range.
@@ -18,11 +18,11 @@ public readonly struct DateTimeRange
1818
public DateTime End { get; }
1919

2020
/// <summary>
21-
/// Construct a <see cref="DateTimeRange"/>.
21+
/// Construct a <see cref="DateTimeRangePart"/>.
2222
/// </summary>
2323
/// <param name="start">The (inclusive) start of the range.</param>
2424
/// <param name="end">The (exclusive) end of the range.</param>
25-
public DateTimeRange(DateTime start, DateTime end)
25+
public DateTimeRangePart(DateTime start, DateTime end)
2626
{
2727
Start = start;
2828
End = end;

src/Seq.Api/ResourceGroups/ApiKeysResourceGroup.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,17 @@ public async Task<MeasurementTimeseriesPart> GetMeasurementTimeseriesAsync(ApiKe
121121
var parameters = new Dictionary<string, object>{ ["id"] = entity.Id, ["measurement"] = measurement };
122122
return await GroupGetAsync<MeasurementTimeseriesPart>("Metric", parameters, cancellationToken);
123123
}
124+
125+
/// <summary>
126+
/// Retrieve a detailed metric for all API keys.
127+
/// </summary>
128+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
129+
/// <param name="measurement">The measurement to get.</param>
130+
/// <returns></returns>
131+
public async Task<Dictionary<string, MeasurementTimeseriesPart>> GetAllMeasurementTimeseriesAsync(string measurement, CancellationToken cancellationToken = default)
132+
{
133+
var parameters = new Dictionary<string, object>{ ["measurement"] = measurement };
134+
return await GroupGetAsync<Dictionary<string, MeasurementTimeseriesPart>>("Metrics", parameters, cancellationToken);
135+
}
124136
}
125137
}

src/Seq.Api/Seq.Api.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<Description>Client library for the Seq HTTP API.</Description>
4-
<VersionPrefix>2023.3.0</VersionPrefix>
4+
<VersionPrefix>2023.4.0</VersionPrefix>
55
<Authors>Datalust;Contributors</Authors>
66
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
77
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -14,6 +14,10 @@
1414
<LangVersion>9</LangVersion>
1515
</PropertyGroup>
1616

17+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
18+
<DefineConstants>$(DefineConstants);SOCKETS_HTTP_HANDLER</DefineConstants>
19+
</PropertyGroup>
20+
1721
<ItemGroup>
1822
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
1923
<PackageReference Include="Tavis.UriTemplates" Version="2.0.0" />

src/Seq.Api/SeqConnection.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class SeqConnection : ILoadResourceGroup, IDisposable
4141
/// <param name="serverUrl">The base URL of the Seq server.</param>
4242
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
4343
/// <param name="useDefaultCredentials">Whether default credentials will be sent with HTTP requests; the default is <c>true</c>.</param>
44-
[Obsolete("Prefer `SeqConnection(serverUrl, apiKey, handler => handler.UseDefaultCredentials = true)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
44+
[Obsolete("Prefer `SeqConnection(serverUrl, apiKey, createHttpMessageHandler)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
4545
public SeqConnection(string serverUrl, string apiKey, bool useDefaultCredentials)
4646
{
4747
if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl));
@@ -55,11 +55,25 @@ public SeqConnection(string serverUrl, string apiKey, bool useDefaultCredentials
5555
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
5656
/// <param name="configureHttpClientHandler">An optional callback to configure the <see cref="HttpClientHandler"/> used when making HTTP requests
5757
/// to the Seq API.</param>
58-
public SeqConnection(string serverUrl, string apiKey = null, Action<HttpClientHandler> configureHttpClientHandler = null)
58+
[Obsolete("Prefer `SeqConnection(serverUrl, apiKey, createHttpMessageHandler)` instead."), EditorBrowsable(EditorBrowsableState.Never)]
59+
public SeqConnection(string serverUrl, string apiKey, Action<HttpClientHandler> configureHttpClientHandler)
5960
{
6061
if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl));
6162
Client = new SeqApiClient(serverUrl, apiKey, configureHttpClientHandler);
6263
}
64+
65+
/// <summary>
66+
/// Construct a <see cref="SeqConnection"/>.
67+
/// </summary>
68+
/// <param name="serverUrl">The base URL of the Seq server.</param>
69+
/// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
70+
/// <param name="createHttpMessageHandler">An optional callback to construct the HTTP message handler used when making requests
71+
/// to the Seq API. The callback receives a <see cref="CookieContainer"/> that is shared with WebSocket requests made by the client.</param>
72+
public SeqConnection(string serverUrl, string apiKey = null, Func<CookieContainer, HttpMessageHandler> createHttpMessageHandler = null)
73+
{
74+
if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl));
75+
Client = new SeqApiClient(serverUrl, apiKey, createHttpMessageHandler);
76+
}
6377

6478
/// <summary>
6579
/// <inheritdoc/>

0 commit comments

Comments
 (0)