Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ if($LASTEXITCODE -ne 0) { exit 1 }

$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "master" -and $revision -ne "local"]
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"]

echo "build: Version suffix is $suffix"

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var installedApps = await connection.Apps.ListAsync();

**To authenticate**, the `SeqConnection` constructor accepts an `apiKey` parameter (make sure the API key permits _user-level access_) or, if you want to log in with personal credentials you can `await connection.Users.LoginAsync(username, password)`.

For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/master/example/SeqTail/Program.cs).
For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/main/example/SeqTail/Program.cs).

#### Creating entities

Expand All @@ -43,7 +43,7 @@ signal.Title = "Signal 123";
await connection.Signals.AddAsync(signal);
```

See the [signal-copy app](https://github.com/datalust/seq-api/blob/master/example/SignalCopy/Program.cs) for an example of this pattern in action.
See the [signal-copy app](https://github.com/datalust/seq-api/blob/main/example/SignalCopy/Program.cs) for an example of this pattern in action.

### Reading events

Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ deploy:
secure: sMicBLl7Z83H/mhX10DL7Yqwa80ZHUbb9fRHKmxd5m2MN2DWAE1kbYH/GPQPFajZ
skip_symbols: true
on:
branch: /^(master|dev)$/
branch: /^(main|dev)$/
- provider: GitHub
auth_token:
secure: hX+cZmW+9BCXy7vyH8myWsYdtQHyzzil9K5yvjJv7dK9XmyrGYYDj/DPzMqsXSjo
artifact: /Seq.Api.*\.nupkg/
tag: v$(appveyor_build_version)
on:
branch: master
branch: main
91 changes: 91 additions & 0 deletions example/SeqEnableAAD/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System;
using System.Threading.Tasks;
using DocoptNet;
using Seq.Api;
using Seq.Api.Model.Settings;

namespace SeqEnableAAD
{
class Program
{
const string Usage = @"seq-enable-aad: enable authentication on your Seq server (for initial setup of a new Seq server only).

Usage:
seq-enable-aad.exe <server> --uname=<un> --tenantid=<tid> --clientid=<cid> --clientkey=<ckey> [--authority=<a>]
seq-enable-aad.exe (-h | --help)

Options:
-h --help Show this screen.
--uname=<un> Username. Azure Active Directory usernames must take the form of an email address.
--tenantid=<tid> Tenant ID.
--clientid=<cid> Client ID.
--clientkey=<ckey> Client key.
--authority=<a> Authority (optional, defaults to 'login.windows.net').
";
static void Main(string[] args)
{
Task.Run(async () =>
{
try
{
var arguments = new Docopt().Apply(Usage, args, version: "Seq Enable AAD 0.1", exit: true);

var server = arguments["<server>"].ToString();
var username = Normalize(arguments["--uname"]);
var tenantId = Normalize(arguments["--tenantid"]);
var clientId = Normalize(arguments["--clientid"]);
var clientKey = Normalize(arguments["--clientkey"]);
var authority = Normalize(arguments["--authority"]);

await Run(server, username, tenantId, clientId, clientKey, authority);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine("seq-enable-aad: {0}", ex);
Console.ResetColor();
Environment.Exit(-1);
}
}).Wait();
}

static string Normalize(ValueObject v)
{
if (v == null) return null;
var s = v.ToString();
return string.IsNullOrWhiteSpace(s) ? null : s;
}

static async Task Run(string server, string username, string tenantId, string clientId, string clientKey, string authority="login.windows.net")
{
var connection = new SeqConnection(server);

var user = await connection.Users.FindCurrentAsync();
var provider = await connection.Settings.FindNamedAsync(SettingName.AuthenticationProvider);
var cid = await connection.Settings.FindNamedAsync(SettingName.AzureADClientId);
var ckey = await connection.Settings.FindNamedAsync(SettingName.AzureADClientKey);
var aut = await connection.Settings.FindNamedAsync(SettingName.AzureADAuthority);
var tid = await connection.Settings.FindNamedAsync(SettingName.AzureADTenantId);

user.Username = username;
provider.Value = "Azure Active Directory";
cid.Value = clientId;
ckey.Value = clientKey;
tid.Value = tenantId;
aut.Value = authority;

await connection.Users.UpdateAsync(user);
await connection.Settings.UpdateAsync(cid);
await connection.Settings.UpdateAsync(ckey);
await connection.Settings.UpdateAsync(tid);
await connection.Settings.UpdateAsync(aut);

await connection.Settings.UpdateAsync(provider); // needs to go before IsAuthenticationEnabled but after the other settings

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
}
}
}
34 changes: 34 additions & 0 deletions example/SeqEnableAAD/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Seq Enable AAD (Azure Active Directory)

Be sure to read the [Seq Azure Active Directory documentation](https://docs.datalust.co/docs/azure-active-directory) to find the manual AAD setup instructions.

## Example usage:

```
seq-enable-aad.exe https://seq.example.com --uname=example@microsoft.com --clientid=xxxxxx --tenantid=xxxxxx --clientkey=xxxxxx --authority=login.windows.net
```

### **Important note:**

#### Windows

Don't forget to set the "canonical URI" which Seq uses as a reply address for AAD.

```
seq config -k api.canonicalUri -v https://seq.example.com
seq service restart
```

#### Linux / Docker

Don't forget to include the BASE_URI which Seq uses as a reply address for AAD.

```
docker run -d \
--restart unless-stopped \
--name seq \
-p 5341:80 \
-e ACCEPT_EULA=Y \
-e BASE_URI=https://seq.example.com \
datalust/seq:latest
```
17 changes: 17 additions & 0 deletions example/SeqEnableAAD/SeqEnableAAD.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>SeqEnableAuth</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="docopt.net" Version="0.6.1.9" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Seq.Api\Seq.Api.csproj" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions seq-api.sln
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SeqTail", "example\SeqTail\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SignalCopy", "example\SignalCopy\SignalCopy.csproj", "{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeqEnableAAD", "example\SeqEnableAAD\SeqEnableAAD.csproj", "{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -53,6 +55,10 @@ Global
{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Release|Any CPU.Build.0 = Release|Any CPU
{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -63,6 +69,7 @@ Global
{34BBD428-8297-484E-B771-0B72C172C264} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487}
{42CEBFBA-208F-40F1-AC95-13F05F6D5412} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487}
{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487}
{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {20BAB483-FB94-4373-8E4C-0F846B6DBFFC}
Expand Down
10 changes: 10 additions & 0 deletions src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ public class ServerMetricsEntity : Entity
public ServerMetricsEntity()
{
}

/// <summary>
/// The start time in UTC of the events in the memory cache.
/// </summary>
public DateTime? EventStoreCacheStart { get; set; }

/// <summary>
/// The end time in UTC of the events in the memory cache.
/// </summary>
public DateTime? EventStoreCacheEnd { get; set; }

/// <summary>
/// The number of days of events able to fit in the memory cache.
Expand Down
33 changes: 33 additions & 0 deletions src/Seq.Api/Model/Diagnostics/Storage/ColumnDescriptionPart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;

namespace Seq.Api.Model.Diagnostics.Storage
{
/// <summary>
/// A description of a column in a rowset.
/// </summary>
public readonly struct ColumnDescriptionPart
{
/// <summary>
/// A label for the column.
/// </summary>
public string Label { get; }

/// <summary>
/// Additional metadata describing the role of the column; this is separate from,
/// but related to, the runtime type of the column values.
/// </summary>
public ColumnType Type { get; }

/// <summary>
/// Construct a <see cref="ColumnDescriptionPart"/>.
/// </summary>
/// <param name="label">A label for the column.</param>
/// <param name="type">Additional metadata describing the role of the column; this is separate from,
/// but related to, the runtime type of the column values.</param>
public ColumnDescriptionPart(string label, ColumnType type)
{
Label = label ?? throw new ArgumentNullException(nameof(label));
Type = type;
}
}
}
19 changes: 19 additions & 0 deletions src/Seq.Api/Model/Diagnostics/Storage/ColumnType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Seq.Api.Model.Diagnostics.Storage
{
/// <summary>
/// Additional metadata describing the role of a column; this is separate from,
/// but related to, the runtime type of the column values.
/// </summary>
public enum ColumnType
{
/// <summary>
/// The column contains general data.
/// </summary>
General,

/// <summary>
/// The column contains timestamps that may be used to create a timeseries.
/// </summary>
Timestamp,
}
}
19 changes: 19 additions & 0 deletions src/Seq.Api/Model/Diagnostics/Storage/RowsetPart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Seq.Api.Model.Diagnostics.Storage
{
/// <summary>
/// Values in rows and columns.
/// </summary>
public class RowsetPart
{
/// <summary>
/// The columns of the rowset.
/// </summary>
public ColumnDescriptionPart[] Columns { get; set; }

/// <summary>
/// An array of rows, where each row is an array of values
/// corresponding to the columns of the rowset.
/// </summary>
public object[][] Rows { get; set; }
}
}
41 changes: 41 additions & 0 deletions src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © Datalust and contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Seq.Api.Model.Shared;

namespace Seq.Api.Model.Diagnostics.Storage
{
/// <summary>
/// Describes storage space consumed by the event store, for a range
/// of event timestamps.
/// </summary>
public class StorageConsumptionPart
{
/// <summary>
/// The range of timestamps covered by the result.
/// </summary>
public DateTimeRange Range { get; set; }

/// <summary>
/// The duration of the timestamp interval covered by each result.
/// </summary>
public uint IntervalMinutes { get; set; }

/// <summary>
/// A potentially-sparse rowset describing the storage space consumed
/// for a range of timestamp intervals.
/// </summary>
public RowsetPart Results { get; set; }
}
}
11 changes: 11 additions & 0 deletions src/Seq.Api/Model/License/LicenseEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public class LicenseEntity : Entity
/// </summary>
public bool IsSingleUser { get; set; }

/// <summary>
/// If the license is a subscription, the subscription id.
/// </summary>
public string SubscriptionId { get; set; }

/// <summary>
/// Information about the status of the license.
/// </summary>
Expand All @@ -56,5 +61,11 @@ public class LicenseEntity : Entity
/// the license has no user limit.
/// </summary>
public int? LicensedUsers { get; set; }

/// <summary>
/// If the license is for a subscription, automatically check datalust.co and
/// update the license when the subscription is renewed or tier changed.
/// </summary>
public bool AutomaticallyRefresh { get; set; }
}
}
Loading