Skip to content

Commit 78b71d9

Browse files
authored
Merge pull request #139 from datalust/dev
2024.3.0 Release
2 parents 85d9acd + 4c650b2 commit 78b71d9

File tree

13 files changed

+251
-9
lines changed

13 files changed

+251
-9
lines changed

example/SeqEnableAAD/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static async Task Run(string server, string? username, string? tenantId, string?
6060
var tid = await connection.Settings.FindNamedAsync(SettingName.EntraIDTenantId);
6161

6262
user.Username = username;
63-
provider.Value = "Azure Active Directory";
63+
provider.Value = "Microsoft Entra ID";
6464
cid.Value = clientId;
6565
ckey.Value = clientKey;
6666
tid.Value = tenantId;
@@ -77,4 +77,4 @@ static async Task Run(string server, string? username, string? tenantId, string?
7777
var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled);
7878
iae.Value = true;
7979
await connection.Settings.UpdateAsync(iae); // this update needs to happen last, as enabling auth will lock this connection out
80-
}
80+
}

src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs renamed to src/Seq.Api/Model/Diagnostics/ServerMetricsPart.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313
// limitations under the License.
1414

1515
using System;
16-
using System.Collections.Generic;
1716

1817
namespace Seq.Api.Model.Diagnostics
1918
{
2019
/// <summary>
2120
/// Metrics describing the state and performance of the Seq server.
2221
/// </summary>
23-
public class ServerMetricsEntity : Entity
22+
/// <remarks>This information is not preserved across server restarts or fail-over.</remarks>
23+
public class ServerMetricsPart
2424
{
2525
/// <summary>
26-
/// Construct a <see cref="ServerMetricsEntity"/>.
26+
/// Construct a <see cref="ServerMetricsPart"/>.
2727
/// </summary>
28-
public ServerMetricsEntity()
28+
public ServerMetricsPart()
2929
{
3030
}
3131

@@ -34,6 +34,16 @@ public ServerMetricsEntity()
3434
/// </summary>
3535
public long? EventStoreDiskRemainingBytes { get; set; }
3636

37+
/// <summary>
38+
/// The total time spent indexing the event store in the last 24 hours.
39+
/// </summary>
40+
public TimeSpan EventStoreIndexingTimeLastDay { get; set; }
41+
42+
/// <summary>
43+
/// The total time spent writing events to disk in the last minute.
44+
/// </summary>
45+
public TimeSpan EventStoreWriteTimeLastMinute { get; set; }
46+
3747
/// <summary>
3848
/// The number of events that arrived at the ingestion endpoint in the past minute.
3949
/// </summary>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace Seq.Api.Model.Indexes
2+
{
3+
/// <summary>
4+
/// An index over the event stream. May be one of several types discriminated by <see cref="IndexedEntityType"/>.
5+
/// </summary>
6+
public class IndexEntity: Entity
7+
{
8+
/// <summary>
9+
/// The `Id` of the associated entity (Signal, Alert or Expression index).
10+
/// </summary>
11+
public string IndexedEntityId { get; set; }
12+
13+
/// <summary>
14+
/// The type of this index.
15+
/// </summary>
16+
public IndexedEntityType IndexedEntityType { get; set; }
17+
18+
/// <summary>
19+
/// The owner / creator of this index.
20+
/// </summary>
21+
public string OwnerUsername { get; set; }
22+
23+
/// <summary>
24+
/// The name of this index. May not be applicable to all index types.
25+
/// </summary>
26+
public string Label { get; set; }
27+
28+
/// <summary>
29+
/// The storage used by this index.
30+
/// </summary>
31+
public ulong StorageBytes { get; set; }
32+
}
33+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Seq.Api.Model.Indexes
2+
{
3+
/// <summary>
4+
/// The type of the index.
5+
/// </summary>
6+
public enum IndexedEntityType
7+
{
8+
/// <summary>
9+
/// A predicate index for a signal expression.
10+
/// </summary>
11+
Signal,
12+
13+
/// <summary>
14+
/// An expression index.
15+
/// </summary>
16+
ExpressionIndex,
17+
18+
/// <summary>
19+
/// A predicate index for an alert filter.
20+
/// </summary>
21+
Alert,
22+
}
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Seq.Api.Model.Indexing
2+
{
3+
/// <summary>
4+
/// An index based on an expression.
5+
/// </summary>
6+
public class ExpressionIndexEntity: Entity
7+
{
8+
/// <summary>
9+
/// The expression to be indexed.
10+
/// </summary>
11+
public string Expression { get; set; }
12+
13+
/// <summary>
14+
/// A user-provided description of the index.
15+
/// </summary>
16+
public string Description { get; set; }
17+
}
18+
}

src/Seq.Api/Model/Settings/SettingName.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System;
1616
using Seq.Api.Model.Apps;
1717
using Seq.Api.Model.Updates;
18+
using Seq.Api.Model.Users;
1819
using Seq.Api.ResourceGroups;
1920

2021
namespace Seq.Api.Model.Settings
@@ -124,6 +125,16 @@ public enum SettingName
124125
/// Seq will stop accepting new events.
125126
/// </summary>
126127
MinimumFreeStorageSpace,
128+
129+
/// <summary>
130+
/// A dictionary of `(string, string)` pairs that will be used to initialize the
131+
/// <see cref="UserEntity.Preferences"/> property when preparing new user entities
132+
/// with <see cref="UsersResourceGroup.TemplateAsync"/>, and with automatically
133+
/// provisioning SSO users (when enabled).
134+
/// </summary>
135+
/// <remarks>User preference keys are unconstrained; the Seq UI uses a number of these, but
136+
/// alternative interfaces and integrations may add additional items to this collection.</remarks>
137+
NewUserPreferences,
127138

128139
/// <summary>
129140
/// A comma-separated list of role ids that will be assigned to new users by default.

src/Seq.Api/Model/Signals/SignalEntity.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public SignalEntity()
6767
/// If <c>true</c>, the signal can only be modified by users with the <see cref="Permission.Project"/> permission.
6868
/// </summary>
6969
public bool IsProtected { get; set; }
70+
71+
/// <summary>
72+
/// If <c>true</c>, the signal has no backing index.
73+
/// </summary>
74+
public bool IsIndexSuppressed { get; set; }
7075

7176
/// <summary>
7277
/// How the signal is grouped in the Seq UI.

src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ internal DiagnosticsResourceGroup(ILoadResourceGroup connection)
3838
/// </summary>
3939
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
4040
/// <returns>Current server metrics.</returns>
41-
public async Task<ServerMetricsEntity> GetServerMetricsAsync(CancellationToken cancellationToken = default)
41+
public async Task<ServerMetricsPart> GetServerMetricsAsync(CancellationToken cancellationToken = default)
4242
{
43-
return await GroupGetAsync<ServerMetricsEntity>("ServerMetrics", cancellationToken: cancellationToken).ConfigureAwait(false);
43+
return await GroupGetAsync<ServerMetricsPart>("ServerMetrics", cancellationToken: cancellationToken).ConfigureAwait(false);
4444
}
4545

4646
/// <summary>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Seq.Api.Model;
6+
using Seq.Api.Model.Indexing;
7+
8+
namespace Seq.Api.ResourceGroups
9+
{
10+
/// <summary>
11+
/// Perform operations on expression indexes.
12+
/// </summary>
13+
public class ExpressionIndexesResourceGroup: ApiResourceGroup
14+
{
15+
internal ExpressionIndexesResourceGroup(ILoadResourceGroup connection) : base("ExpressionIndexes", connection)
16+
{
17+
}
18+
19+
/// <summary>
20+
/// Retrieve expression indexes.
21+
/// </summary>
22+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
23+
/// <returns>A list containing matching expression indexes.</returns>
24+
public async Task<List<ExpressionIndexEntity>> ListAsync(CancellationToken cancellationToken = default)
25+
{
26+
return await GroupListAsync<ExpressionIndexEntity>("Items", cancellationToken: cancellationToken).ConfigureAwait(false);
27+
}
28+
29+
/// <summary>
30+
/// Retrieve the expression index with the given id; throws if the entity does not exist.
31+
/// </summary>
32+
/// <param name="id">The id of the expression index.</param>
33+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
34+
/// <returns>The expression index.</returns>
35+
public async Task<ExpressionIndexEntity> FindAsync(string id, CancellationToken cancellationToken = default)
36+
{
37+
if (id == null) throw new ArgumentNullException(nameof(id));
38+
return await GroupGetAsync<ExpressionIndexEntity>("Item", new Dictionary<string, object> { { "id", id } }, cancellationToken).ConfigureAwait(false);
39+
}
40+
41+
/// <summary>
42+
/// Construct an expression index with server defaults pre-initialized.
43+
/// </summary>
44+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
45+
/// <returns>The unsaved expression index.</returns>
46+
public async Task<ExpressionIndexEntity> TemplateAsync(CancellationToken cancellationToken = default)
47+
{
48+
return await GroupGetAsync<ExpressionIndexEntity>("Template", cancellationToken: cancellationToken).ConfigureAwait(false);
49+
}
50+
51+
/// <summary>
52+
/// Add a new expression index.
53+
/// </summary>
54+
/// <param name="entity">The expression index to add.</param>
55+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
56+
/// <returns>The expression index, with server-allocated properties such as <see cref="Entity.Id"/> initialized.</returns>
57+
public async Task<ExpressionIndexEntity> AddAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default)
58+
{
59+
return await GroupCreateAsync<ExpressionIndexEntity, ExpressionIndexEntity>(entity, cancellationToken: cancellationToken).ConfigureAwait(false);
60+
}
61+
62+
/// <summary>
63+
/// Remove an existing expression index.
64+
/// </summary>
65+
/// <param name="entity">The expression index to remove.</param>
66+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
67+
/// <returns>A task indicating completion.</returns>
68+
public async Task RemoveAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default)
69+
{
70+
await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false);
71+
}
72+
}
73+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Seq.Api.Model.Alerting;
6+
using Seq.Api.Model.Indexes;
7+
using Seq.Api.Model.Indexing;
8+
using Seq.Api.Model.Signals;
9+
10+
namespace Seq.Api.ResourceGroups
11+
{
12+
/// <summary>
13+
/// Statistics about indexes.
14+
/// </summary>
15+
public class IndexesResourceGroup : ApiResourceGroup
16+
{
17+
internal IndexesResourceGroup(ILoadResourceGroup connection)
18+
: base("Indexes", connection)
19+
{
20+
}
21+
22+
/// <summary>
23+
/// Retrieve the index with the given id; throws if the entity does not exist.
24+
/// </summary>
25+
/// <param name="id">The id of the index.</param>
26+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
27+
/// <returns>The index.</returns>
28+
public async Task<IndexEntity> FindAsync(string id, CancellationToken cancellationToken = default)
29+
{
30+
if (id == null) throw new ArgumentNullException(nameof(id));
31+
return await GroupGetAsync<IndexEntity>("Item", new Dictionary<string, object> { { "id", id } }, cancellationToken).ConfigureAwait(false);
32+
}
33+
34+
/// <summary>
35+
/// Retrieve statistics on all indexes.
36+
/// </summary>
37+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
38+
/// <returns>A list containing matching expression indexes.</returns>
39+
public async Task<List<IndexEntity>> ListAsync(CancellationToken cancellationToken = default)
40+
{
41+
return await GroupListAsync<IndexEntity>("Items", cancellationToken: cancellationToken).ConfigureAwait(false);
42+
}
43+
44+
/// <summary>
45+
/// Suppress an index. Not all index types can be suppressed: signal indexes do support suppression, in the case
46+
/// of which the <see cref="SignalEntity.IsIndexSuppressed"/> flag will be set to <c langword="false"/>.
47+
/// Expression indexes can only be suppressed by deleting the associated <see cref="ExpressionIndexEntity"/>
48+
/// and alert indexes can only be suppressed by deleting the corresponding <see cref="AlertEntity"/>.
49+
/// </summary>
50+
/// <param name="entity">The index to suppress.</param>
51+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
52+
/// <returns>A task indicating completion.</returns>
53+
public async Task SuppressAsync(IndexEntity entity, CancellationToken cancellationToken = default)
54+
{
55+
await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)