diff --git a/docker-compose.yml b/docker-compose.yml
index 492f7c2..57c28ab 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,7 +4,7 @@ services:
context: .
dockerfile: ./src/Imprink.WebApi/Dockerfile
expose:
- - "80"
+ - "8080"
environment:
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
- ConnectionStrings__DefaultConnection=Server=${SQL_SERVER};Database=${SQL_DATABASE};User Id=${SQL_USER_ID};Password=${SQL_PASSWORD};Encrypt=false;TrustServerCertificate=true;MultipleActiveResultSets=true;
@@ -20,6 +20,20 @@ services:
networks:
- app-network
+ seq:
+ image: datalust/seq
+ expose:
+ - "80"
+ - "5341"
+ ports:
+ - "5341:5341"
+ environment:
+ - ACCEPT_EULA=Y
+ - SEQ_CACHE_SYSTEMRAMTARGET=0.9
+ - BASE_URI=https://impr.ink/seq
+ networks:
+ - app-network
+
webui:
image: node:18-alpine
working_dir: /app
@@ -45,15 +59,16 @@ services:
networks:
- app-network
-
mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: sqlserver
ports:
- "1433:1433"
environment:
- SA_PASSWORD: "${SQL_PASSWORD}"
- ACCEPT_EULA: "Y"
+ - SA_PASSWORD=${SQL_PASSWORD}
+ - ACCEPT_EULA=Y
+ - MSSQL_AGENT_ENABLED=false
+ - MSSQL_LOG_LEVEL=WARN
restart: unless-stopped
networks:
- app-network
@@ -70,6 +85,7 @@ services:
depends_on:
- webapi
- webui
+ - seq
networks:
- app-network
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
index 19fb768..1465088 100644
--- a/nginx/nginx.conf
+++ b/nginx/nginx.conf
@@ -17,6 +17,10 @@ http {
server webui:3000;
}
+ upstream seq {
+ server seq:80;
+ }
+
server {
listen 80;
server_name impr.ink;
@@ -47,6 +51,27 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
+ location /seq {
+ proxy_pass http://seq;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-Prefix /seq;
+
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+
+ proxy_redirect off;
+
+ rewrite ^/seq$ /seq/ redirect;
+ rewrite ^/seq/(.*)$ /$1 break;
+ }
+
location / {
proxy_pass http://webui/;
proxy_http_version 1.1;
diff --git a/src/Imprink.WebApi/Imprink.WebApi.csproj b/src/Imprink.WebApi/Imprink.WebApi.csproj
index 5ed647b..f0f6e50 100644
--- a/src/Imprink.WebApi/Imprink.WebApi.csproj
+++ b/src/Imprink.WebApi/Imprink.WebApi.csproj
@@ -15,6 +15,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+
diff --git a/src/Imprink.WebApi/Middleware/RequestTimingMiddleware.cs b/src/Imprink.WebApi/Middleware/RequestTimingMiddleware.cs
new file mode 100644
index 0000000..5cd5dde
--- /dev/null
+++ b/src/Imprink.WebApi/Middleware/RequestTimingMiddleware.cs
@@ -0,0 +1,37 @@
+using System.Diagnostics;
+
+namespace Imprink.WebApi.Middleware;
+
+public class RequestTimingMiddleware(RequestDelegate next, ILogger logger)
+{
+ public async Task InvokeAsync(HttpContext context)
+ {
+ var stopwatch = Stopwatch.StartNew();
+
+ try
+ {
+ await next(context);
+ }
+ finally
+ {
+ stopwatch.Stop();
+
+ var elapsedMs = stopwatch.ElapsedMilliseconds;
+ var method = context.Request.Method;
+ var path = context.Request.Path;
+ var statusCode = context.Response.StatusCode;
+
+ logger.LogInformation(
+ "Request {Method} {Path} completed in {ElapsedMs}ms with status code {StatusCode}",
+ method, path, elapsedMs, statusCode);
+ }
+ }
+}
+
+public static class RequestTimingMiddlewareExtensions
+{
+ public static IApplicationBuilder UseRequestTiming(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+}
\ No newline at end of file
diff --git a/src/Imprink.WebApi/Program.cs b/src/Imprink.WebApi/Program.cs
index 492b1c9..894e773 100644
--- a/src/Imprink.WebApi/Program.cs
+++ b/src/Imprink.WebApi/Program.cs
@@ -1,7 +1,17 @@
using Imprink.WebApi;
+using Serilog;
var builder = WebApplication.CreateBuilder(args);
+Log.Logger = new LoggerConfiguration()
+ .WriteTo.Seq("http://seq:5341",
+ restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information)
+ .Enrich.FromLogContext()
+ .WriteTo.Console()
+ .CreateLogger();
+
+builder.Host.UseSerilog();
+
Startup.ConfigureServices(builder);
var app = builder.Build();
diff --git a/src/Imprink.WebApi/Startup.cs b/src/Imprink.WebApi/Startup.cs
index 5d8d602..820fd1e 100644
--- a/src/Imprink.WebApi/Startup.cs
+++ b/src/Imprink.WebApi/Startup.cs
@@ -5,6 +5,7 @@ using Imprink.Domain.Repositories;
using Imprink.Infrastructure;
using Imprink.Infrastructure.Database;
using Imprink.Infrastructure.Repositories;
+using Imprink.WebApi.Middleware;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
@@ -94,6 +95,8 @@ public static class Startup
Console.WriteLine($"An error occurred while applying migrations: {ex.Message}");
}
}
+
+ app.UseRequestTiming();
if (env.IsDevelopment())
{
diff --git a/webui/src/app/token/route.js b/webui/src/app/token/route.js
index 399a38d..d649080 100644
--- a/webui/src/app/token/route.js
+++ b/webui/src/app/token/route.js
@@ -22,7 +22,7 @@ export async function GET() {
headers: { Cookie: `access_token=${token}` }
});
- NextResponse.json({ message: 'Access token set in cookie' });
+ return NextResponse.json({ message: 'Access token set in cookie' });
} catch (error) {
console.error('Error in /api/token:', error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });