diff --git a/example/SeqEnableAAD/Program.cs b/example/SeqEnableAAD/Program.cs index 93d5a59..1e8523f 100644 --- a/example/SeqEnableAAD/Program.cs +++ b/example/SeqEnableAAD/Program.cs @@ -60,7 +60,7 @@ static async Task Run(string server, string? username, string? tenantId, string? var tid = await connection.Settings.FindNamedAsync(SettingName.EntraIDTenantId); user.Username = username; - provider.Value = "Azure Active Directory"; + provider.Value = "Microsoft Entra ID"; cid.Value = clientId; ckey.Value = clientKey; tid.Value = tenantId; @@ -77,4 +77,4 @@ static async Task Run(string server, string? username, string? tenantId, string? var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled); iae.Value = true; await connection.Settings.UpdateAsync(iae); // this update needs to happen last, as enabling auth will lock this connection out -} \ No newline at end of file +} diff --git a/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs b/src/Seq.Api/Model/Diagnostics/ServerMetricsPart.cs similarity index 80% rename from src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs rename to src/Seq.Api/Model/Diagnostics/ServerMetricsPart.cs index 9342d2c..9b75681 100644 --- a/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs +++ b/src/Seq.Api/Model/Diagnostics/ServerMetricsPart.cs @@ -13,19 +13,19 @@ // limitations under the License. using System; -using System.Collections.Generic; namespace Seq.Api.Model.Diagnostics { /// /// Metrics describing the state and performance of the Seq server. /// - public class ServerMetricsEntity : Entity + /// This information is not preserved across server restarts or fail-over. + public class ServerMetricsPart { /// - /// Construct a . + /// Construct a . /// - public ServerMetricsEntity() + public ServerMetricsPart() { } @@ -34,6 +34,16 @@ public ServerMetricsEntity() /// public long? EventStoreDiskRemainingBytes { get; set; } + /// + /// The total time spent indexing the event store in the last 24 hours. + /// + public TimeSpan EventStoreIndexingTimeLastDay { get; set; } + + /// + /// The total time spent writing events to disk in the last minute. + /// + public TimeSpan EventStoreWriteTimeLastMinute { get; set; } + /// /// The number of events that arrived at the ingestion endpoint in the past minute. /// diff --git a/src/Seq.Api/Model/Indexes/IndexEntity.cs b/src/Seq.Api/Model/Indexes/IndexEntity.cs new file mode 100644 index 0000000..6b92295 --- /dev/null +++ b/src/Seq.Api/Model/Indexes/IndexEntity.cs @@ -0,0 +1,33 @@ +namespace Seq.Api.Model.Indexes +{ + /// + /// An index over the event stream. May be one of several types discriminated by . + /// + public class IndexEntity: Entity + { + /// + /// The `Id` of the associated entity (Signal, Alert or Expression index). + /// + public string IndexedEntityId { get; set; } + + /// + /// The type of this index. + /// + public IndexedEntityType IndexedEntityType { get; set; } + + /// + /// The owner / creator of this index. + /// + public string OwnerUsername { get; set; } + + /// + /// The name of this index. May not be applicable to all index types. + /// + public string Label { get; set; } + + /// + /// The storage used by this index. + /// + public ulong StorageBytes { get; set; } + } +} diff --git a/src/Seq.Api/Model/Indexes/IndexedEntityType.cs b/src/Seq.Api/Model/Indexes/IndexedEntityType.cs new file mode 100644 index 0000000..cdfb60b --- /dev/null +++ b/src/Seq.Api/Model/Indexes/IndexedEntityType.cs @@ -0,0 +1,23 @@ +namespace Seq.Api.Model.Indexes +{ + /// + /// The type of the index. + /// + public enum IndexedEntityType + { + /// + /// A predicate index for a signal expression. + /// + Signal, + + /// + /// An expression index. + /// + ExpressionIndex, + + /// + /// A predicate index for an alert filter. + /// + Alert, + } +} \ No newline at end of file diff --git a/src/Seq.Api/Model/Indexing/ExpressionIndexEntity.cs b/src/Seq.Api/Model/Indexing/ExpressionIndexEntity.cs new file mode 100644 index 0000000..e0d3b86 --- /dev/null +++ b/src/Seq.Api/Model/Indexing/ExpressionIndexEntity.cs @@ -0,0 +1,18 @@ +namespace Seq.Api.Model.Indexing +{ + /// + /// An index based on an expression. + /// + public class ExpressionIndexEntity: Entity + { + /// + /// The expression to be indexed. + /// + public string Expression { get; set; } + + /// + /// A user-provided description of the index. + /// + public string Description { get; set; } + } +} \ No newline at end of file diff --git a/src/Seq.Api/Model/Settings/SettingName.cs b/src/Seq.Api/Model/Settings/SettingName.cs index 1a36756..9609e57 100644 --- a/src/Seq.Api/Model/Settings/SettingName.cs +++ b/src/Seq.Api/Model/Settings/SettingName.cs @@ -15,6 +15,7 @@ using System; using Seq.Api.Model.Apps; using Seq.Api.Model.Updates; +using Seq.Api.Model.Users; using Seq.Api.ResourceGroups; namespace Seq.Api.Model.Settings @@ -124,6 +125,16 @@ public enum SettingName /// Seq will stop accepting new events. /// MinimumFreeStorageSpace, + + /// + /// A dictionary of `(string, string)` pairs that will be used to initialize the + /// property when preparing new user entities + /// with , and with automatically + /// provisioning SSO users (when enabled). + /// + /// User preference keys are unconstrained; the Seq UI uses a number of these, but + /// alternative interfaces and integrations may add additional items to this collection. + NewUserPreferences, /// /// A comma-separated list of role ids that will be assigned to new users by default. diff --git a/src/Seq.Api/Model/Signals/SignalEntity.cs b/src/Seq.Api/Model/Signals/SignalEntity.cs index 9c90ba2..82fd86d 100644 --- a/src/Seq.Api/Model/Signals/SignalEntity.cs +++ b/src/Seq.Api/Model/Signals/SignalEntity.cs @@ -67,6 +67,11 @@ public SignalEntity() /// If true, the signal can only be modified by users with the permission. /// public bool IsProtected { get; set; } + + /// + /// If true, the signal has no backing index. + /// + public bool IsIndexSuppressed { get; set; } /// /// How the signal is grouped in the Seq UI. diff --git a/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs b/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs index d1616b9..5ba40d8 100644 --- a/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs +++ b/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs @@ -38,9 +38,9 @@ internal DiagnosticsResourceGroup(ILoadResourceGroup connection) /// /// A allowing the operation to be canceled. /// Current server metrics. - public async Task GetServerMetricsAsync(CancellationToken cancellationToken = default) + public async Task GetServerMetricsAsync(CancellationToken cancellationToken = default) { - return await GroupGetAsync("ServerMetrics", cancellationToken: cancellationToken).ConfigureAwait(false); + return await GroupGetAsync("ServerMetrics", cancellationToken: cancellationToken).ConfigureAwait(false); } /// diff --git a/src/Seq.Api/ResourceGroups/ExpressionIndexesResourceGroup.cs b/src/Seq.Api/ResourceGroups/ExpressionIndexesResourceGroup.cs new file mode 100644 index 0000000..b804093 --- /dev/null +++ b/src/Seq.Api/ResourceGroups/ExpressionIndexesResourceGroup.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Seq.Api.Model; +using Seq.Api.Model.Indexing; + +namespace Seq.Api.ResourceGroups +{ + /// + /// Perform operations on expression indexes. + /// + public class ExpressionIndexesResourceGroup: ApiResourceGroup + { + internal ExpressionIndexesResourceGroup(ILoadResourceGroup connection) : base("ExpressionIndexes", connection) + { + } + + /// + /// Retrieve expression indexes. + /// + /// allowing the operation to be canceled. + /// A list containing matching expression indexes. + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await GroupListAsync("Items", cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Retrieve the expression index with the given id; throws if the entity does not exist. + /// + /// The id of the expression index. + /// A allowing the operation to be canceled. + /// The expression index. + public async Task FindAsync(string id, CancellationToken cancellationToken = default) + { + if (id == null) throw new ArgumentNullException(nameof(id)); + return await GroupGetAsync("Item", new Dictionary { { "id", id } }, cancellationToken).ConfigureAwait(false); + } + + /// + /// Construct an expression index with server defaults pre-initialized. + /// + /// allowing the operation to be canceled. + /// The unsaved expression index. + public async Task TemplateAsync(CancellationToken cancellationToken = default) + { + return await GroupGetAsync("Template", cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Add a new expression index. + /// + /// The expression index to add. + /// A allowing the operation to be canceled. + /// The expression index, with server-allocated properties such as initialized. + public async Task AddAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default) + { + return await GroupCreateAsync(entity, cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Remove an existing expression index. + /// + /// The expression index to remove. + /// A allowing the operation to be canceled. + /// A task indicating completion. + public async Task RemoveAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default) + { + await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false); + } + } +} \ No newline at end of file diff --git a/src/Seq.Api/ResourceGroups/IndexesResourceGroup.cs b/src/Seq.Api/ResourceGroups/IndexesResourceGroup.cs new file mode 100644 index 0000000..5ee3f74 --- /dev/null +++ b/src/Seq.Api/ResourceGroups/IndexesResourceGroup.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Seq.Api.Model.Alerting; +using Seq.Api.Model.Indexes; +using Seq.Api.Model.Indexing; +using Seq.Api.Model.Signals; + +namespace Seq.Api.ResourceGroups +{ + /// + /// Statistics about indexes. + /// + public class IndexesResourceGroup : ApiResourceGroup + { + internal IndexesResourceGroup(ILoadResourceGroup connection) + : base("Indexes", connection) + { + } + + /// + /// Retrieve the index with the given id; throws if the entity does not exist. + /// + /// The id of the index. + /// A allowing the operation to be canceled. + /// The index. + public async Task FindAsync(string id, CancellationToken cancellationToken = default) + { + if (id == null) throw new ArgumentNullException(nameof(id)); + return await GroupGetAsync("Item", new Dictionary { { "id", id } }, cancellationToken).ConfigureAwait(false); + } + + /// + /// Retrieve statistics on all indexes. + /// + /// allowing the operation to be canceled. + /// A list containing matching expression indexes. + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await GroupListAsync("Items", cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Suppress an index. Not all index types can be suppressed: signal indexes do support suppression, in the case + /// of which the flag will be set to . + /// Expression indexes can only be suppressed by deleting the associated + /// and alert indexes can only be suppressed by deleting the corresponding . + /// + /// The index to suppress. + /// A allowing the operation to be canceled. + /// A task indicating completion. + public async Task SuppressAsync(IndexEntity entity, CancellationToken cancellationToken = default) + { + await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/Seq.Api/ResourceGroups/SignalsResourceGroup.cs b/src/Seq.Api/ResourceGroups/SignalsResourceGroup.cs index d74c680..7249714 100644 --- a/src/Seq.Api/ResourceGroups/SignalsResourceGroup.cs +++ b/src/Seq.Api/ResourceGroups/SignalsResourceGroup.cs @@ -78,6 +78,7 @@ public async Task AddAsync(SignalEntity entity, CancellationToken { return await GroupCreateAsync(entity, cancellationToken: cancellationToken).ConfigureAwait(false); } + /// /// Remove an existing signal. /// diff --git a/src/Seq.Api/Seq.Api.csproj b/src/Seq.Api/Seq.Api.csproj index 13e4ee2..9eed51c 100644 --- a/src/Seq.Api/Seq.Api.csproj +++ b/src/Seq.Api/Seq.Api.csproj @@ -1,7 +1,7 @@ Client library for the Seq HTTP API. - 2024.2.0 + 2024.3.0 Datalust;Contributors netstandard2.0;net6.0 true diff --git a/src/Seq.Api/SeqConnection.cs b/src/Seq.Api/SeqConnection.cs index 35df2ce..6032e27 100644 --- a/src/Seq.Api/SeqConnection.cs +++ b/src/Seq.Api/SeqConnection.cs @@ -149,12 +149,22 @@ public void Dispose() /// Perform operations on queries and filter expressions. /// public ExpressionsResourceGroup Expressions => new ExpressionsResourceGroup(this); + + /// + /// Perform operations on expression indexes. + /// + public ExpressionIndexesResourceGroup ExpressionIndexes => new ExpressionIndexesResourceGroup(this); /// /// Perform operations on NuGet feeds. /// public FeedsResourceGroup Feeds => new FeedsResourceGroup(this); + /// + /// Statistics about indexes. + /// + public IndexesResourceGroup Indexes => new IndexesResourceGroup(this); + /// /// Perform operations on the Seq license certificate. ///