Skip to content

Commit b2c65b4

Browse files
author
Om-Suryawanshi
committed
Logging
1 parent cd6870a commit b2c65b4

File tree

9 files changed

+220
-14
lines changed

9 files changed

+220
-14
lines changed

Controllers/LogsController.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using LabReportAPI.Services;
2+
using LabReportAPI;
3+
using Microsoft.AspNetCore.Mvc;
4+
5+
namespace LabReportAPI.Controllers
6+
{
7+
[ApiController]
8+
[Route("api/[controller]")]
9+
public class LogsController : ControllerBase
10+
{
11+
private readonly ILogService _logService;
12+
13+
public LogsController(ILogService logService)
14+
{
15+
_logService = logService;
16+
}
17+
18+
[HttpGet]
19+
public ActionResult<IEnumerable<LogEntry>> GetLogs()
20+
{
21+
return Ok(_logService.GetLogs());
22+
}
23+
}
24+
}

Models/LogEntry.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class LogEntry
2+
{
3+
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
4+
public string Level { get; set; } = "INFO";
5+
public string Message { get; set; } = "";
6+
public string? Context { get; set; }
7+
}

Program.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
using LabReportAPI.Services;
2+
13
var builder = WebApplication.CreateBuilder(args);
24

35
// Add services
46
builder.Services.AddControllers();
57
builder.Services.AddHostedService<TcpListenerService>();
68
builder.Services.Configure<LabSettings>(builder.Configuration.GetSection("LabSettings"));
9+
builder.Services.AddSingleton<ILogService, LogService>();
10+
711

812
var app = builder.Build();
913

14+
app.UseDefaultFiles();
15+
app.UseStaticFiles();
16+
1017
app.UseRouting();
1118
app.MapControllers();
1219

Services/ILogService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace LabReportAPI.Services
2+
{
3+
public interface ILogService
4+
{
5+
void Log(string message, string level = "INFO", string? context = null);
6+
IEnumerable<LogEntry> GetLogs();
7+
}
8+
}

Services/LogService.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace LabReportAPI.Services
2+
{
3+
public class LogService : ILogService
4+
{
5+
private readonly List<LogEntry> _logs = new();
6+
private readonly object _lock = new();
7+
8+
public void Log(string message, string level = "INFO", string? context = null)
9+
{
10+
var entry = new LogEntry { Message = message, Level = level, Context = context };
11+
lock (_lock)
12+
{
13+
_logs.Add(entry);
14+
if (_logs.Count > 1000) _logs.RemoveAt(0); // keep memory usage in check
15+
}
16+
17+
// Optional: Also write to file
18+
File.AppendAllText("logs/log.txt", $"{entry.Timestamp:o} [{level}] ({context}) {message}{Environment.NewLine}");
19+
}
20+
21+
public IEnumerable<LogEntry> GetLogs()
22+
{
23+
lock (_lock)
24+
{
25+
return _logs.ToList();
26+
}
27+
}
28+
}
29+
}

Services/TcpListenerService.cs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
using System;
2-
using System.IO;
31
using System.Collections.Concurrent;
4-
using System.Collections.Generic;
5-
using System.Linq;
62
using System.Net;
73
using System.Net.Sockets;
84
using System.Text;
95
using System.Text.Json;
106
using System.Text.RegularExpressions;
11-
using System.Threading;
12-
using System.Threading.Tasks;
13-
using Microsoft.Extensions.Hosting;
14-
using Microsoft.Extensions.Logging;
157
using Microsoft.Extensions.Options;
16-
8+
using LabReportAPI.Services;
179

1810
public class TcpListenerService : BackgroundService
1911
{
2012
public static TcpListenerService? Instance { get; private set; }
2113

2214
private readonly ILogger<TcpListenerService> _logger;
15+
private readonly ILogService _logService;
2316
private readonly LabSettings _settings;
2417
private TcpListener? _tcpListener;
2518

@@ -49,9 +42,10 @@ private class ClientStats
4942
public DateTime LastSeen { get; set; }
5043
}
5144

52-
public TcpListenerService(ILogger<TcpListenerService> logger, IOptions<LabSettings> settings)
45+
public TcpListenerService(ILogger<TcpListenerService> logger, IOptions<LabSettings> settings, ILogService logService)
5346
{
5447
_logger = logger;
48+
_logService = logService;
5549
_settings = settings.Value;
5650
Instance = this;
5751
}
@@ -65,6 +59,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
6559
{
6660
_tcpListener.Start();
6761
_logger.LogInformation($"✅ TCP Server started on {_localIp}:{Port}");
62+
_logService.Log($"TCP Listener started", "INFO", "{TcpListenerService}");
63+
6864

6965
// Background task for saving data
7066
var saveTask = SaveMessagesToJsonPeriodically(stoppingToken);
@@ -76,25 +72,34 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
7672
}
7773

7874
_logger.LogInformation("🛑 Cancellation requested. Beginning graceful shutdown...");
75+
_logService.Log("TCP Listener Cancellation requested", "INFO", "🛑 Cancellation requested. Beginning graceful shutdown...");
76+
7977
}
8078
catch (OperationCanceledException)
8179
{
80+
_logService.Log("TCP Listener Cancellation requested", "INFO", "🟡 TCP server is shutting down due to cancellation request.");
8281
_logger.LogInformation("🟡 TCP server is shutting down due to cancellation request.");
8382
}
8483
catch (Exception ex)
8584
{
8685
_logger.LogError(ex, "❌ TCP listener fatal error");
86+
_logService.Log("TCP Listener fatal error", "ERROR", "❌ TCP listener fatal error.");
87+
8788
}
8889
finally
8990
{
9091
try
9192
{
9293
_tcpListener?.Stop();
9394
_logger.LogInformation("🔌 TCP listener stopped.");
95+
_logService.Log("TCP Listener stopped", "INFO", "🔌 TCP listener stopped.");
96+
9497
}
9598
catch (Exception ex)
9699
{
97100
_logger.LogError(ex, "❌ Error during TCP listener shutdown.");
101+
_logService.Log("ERROR During TCP Listener Shutdown", "ERROR", "❌ Error during TCP listener shutdown....");
102+
98103
}
99104
}
100105
}
@@ -109,6 +114,8 @@ private async Task HandleClientAsync(TcpClient client, CancellationToken ct)
109114
if (BlockedIps.Contains(clientIp))
110115
{
111116
_logger.LogWarning($"Blocked IP attempted connection: {clientIp}");
117+
_logService.Log("Blocked IP attempted connection", "WARNING", $"Blocked IP: {clientIp}");
118+
112119
client.Close();
113120
return;
114121
}
@@ -131,6 +138,8 @@ private async Task HandleClientAsync(TcpClient client, CancellationToken ct)
131138
if (bytesRead == 0)
132139
{
133140
_logger.LogInformation("Client disconnected gracefully");
141+
// _logService.Log("Client disconnected gracefully", "INFO", $" IP: {clientIp}");
142+
134143
break;
135144
}
136145

@@ -165,6 +174,7 @@ private async Task ProcessMessageBuffer(StringBuilder buffer, NetworkStream stre
165174
if (stxIndex == -1 || etxIndex <= stxIndex)
166175
{
167176
_logger.LogWarning($"Malformed message from {clientIp}: {buffer}");
177+
_logService.Log("Malformed message", "WARNING", $"Client IP: {clientIp}");
168178
await SendResponse(stream, "\x15", ct); // NAK
169179
buffer.Clear();
170180
RegisterError(clientIp); // Don't block immediately
@@ -177,6 +187,7 @@ private async Task ProcessMessageBuffer(StringBuilder buffer, NetworkStream stre
177187
if (ContainsMaliciousContent(message))
178188
{
179189
_logger.LogWarning($"[MALICIOUS INPUT] from {clientIp}: {message}");
190+
_logService.Log("MALICIOUS INPUT", "WARNING", $"Client IP: {clientIp}");
180191
await SendResponse(stream, "\x15", ct); // NAK
181192
RegisterError(clientIp);
182193
continue;
@@ -193,12 +204,14 @@ private async Task ProcessMessageBuffer(StringBuilder buffer, NetworkStream stre
193204
if (!ValidateLabMessage(message))
194205
{
195206
_logger.LogWarning($"[INVALID MESSAGE] from {clientIp}: {message}");
207+
_logService.Log("INVALID MESSAGE", "WARNING", $"Client IP: {clientIp}");
196208
await SendResponse(stream, "\x15", ct); // NAK
197209
RegisterError(clientIp);
198210
continue;
199211
}
200212

201213
_logger.LogInformation($"[VALID MESSAGE] from {clientIp}: {message}");
214+
_logService.Log("Valid Message", "INFO", $"Client IP: {clientIp}");
202215
await ProcessLabData(message);
203216
await SendResponse(stream, "\x06", ct); // ACK
204217
}
@@ -228,6 +241,8 @@ private async Task ProcessLabData(string message)
228241
LabMessages.Add(labMessage);
229242
_lastReceivedMessage = DateTime.UtcNow;
230243
_logger.LogInformation($"Processed: {message}");
244+
// _logService.Log("Processed", "INFO", $"Client IP: {clientIp}");
245+
231246
await Task.CompletedTask;
232247
}
233248

@@ -345,6 +360,7 @@ private async Task SaveMessagesToJsonPeriodically(CancellationToken stoppingToke
345360
if (!usbDrive.IsReady || usbDrive.DriveType != DriveType.Removable)
346361
{
347362
_logger.LogWarning("Configured USB path is invalid or not ready.");
363+
_logService.Log("Configured USB path is invalid or not ready.", "WARNING", "Invalid Path");
348364
usbDrive = null;
349365
}
350366
}
@@ -357,6 +373,8 @@ private async Task SaveMessagesToJsonPeriodically(CancellationToken stoppingToke
357373
if (usbDrive == null)
358374
{
359375
_logger.LogWarning("⚠️ No USB drive detected.");
376+
_logService.Log("No USB Drive detected.", "WARNING", "⚠️ No USB drive detected.");
377+
360378
_lastWriteStatus = "USB not found";
361379
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
362380
continue;
@@ -384,6 +402,8 @@ private async Task SaveMessagesToJsonPeriodically(CancellationToken stoppingToke
384402

385403
await File.WriteAllTextAsync(path, updatedJson, stoppingToken);
386404
_logger.LogInformation($"✅ Saved {messagesSnapshot.Length} messages to USB at: {path}");
405+
_logService.Log("Data Saved.", "INFO", $"Data Saved to {path}");
406+
387407

388408
while (!LabMessages.IsEmpty)
389409
LabMessages.TryTake(out _);
@@ -395,6 +415,7 @@ private async Task SaveMessagesToJsonPeriodically(CancellationToken stoppingToke
395415
catch (Exception ex)
396416
{
397417
_logger.LogWarning(ex, $"Retrying USB write... attempts left: {retryCount}");
418+
_logService.Log("Retrying USB write...", "WARNING", "Retrying");
398419
_lastWriteStatus = $"Retrying write... {retryCount} attempts left";
399420
await Task.Delay(2000, stoppingToken);
400421
}
@@ -403,6 +424,7 @@ private async Task SaveMessagesToJsonPeriodically(CancellationToken stoppingToke
403424
catch (Exception ex)
404425
{
405426
_logger.LogError(ex, "❌ Error detecting USB or writing file.");
427+
_logService.Log("Error detecting USB or writing file.", "WARNING", "❌ Error detecting USB or writing file...");
406428
_lastWriteStatus = "Error writing to USB";
407429
}
408430
}
@@ -453,6 +475,8 @@ private async Task SaveMessagesToUsb(bool force = false)
453475
if (usbDrive == null)
454476
{
455477
_logger.LogWarning("❌ No USB drive detected.");
478+
_logService.Log("No USB drive detected.", "WARNING", "❌ No USB drive detected.");
479+
456480
_lastWriteStatus = "Manual save failed: USB not found";
457481
return;
458482
}
@@ -479,17 +503,23 @@ private async Task SaveMessagesToUsb(bool force = false)
479503

480504
await File.WriteAllTextAsync(path, updatedJson);
481505
_logger.LogInformation($"✅ Manual save: {messagesSnapshot.Length} messages appended to {path}");
506+
_logService.Log("Manual save.", "INFO", "Manual save.");
507+
482508

483509
while (!LabMessages.IsEmpty)
484510
LabMessages.TryTake(out _);
485511

486512
_lastWriteTime = now;
487513
_lastWriteStatus = $"Manual save at {now:HH:mm:ss}";
514+
_logService.Log("Manual save.", "INFO", $"Manual save at {now:HH:mm:ss}");
515+
488516
return;
489517
}
490518
catch (Exception ex)
491519
{
492520
_logger.LogWarning(ex, $"Retrying manual USB write... attempts left: {retryCount}");
521+
_logService.Log("Retrying manual USB write.", "WARNING", "Retrying manual USB write...");
522+
493523
_lastWriteStatus = $"Retrying manual write... {retryCount} left";
494524
await Task.Delay(2000);
495525
}
@@ -512,6 +542,4 @@ private async Task SaveMessagesToUsb(bool force = false)
512542
public static DateTime GetLastMessageTime() => _lastReceivedMessage;
513543
public static string GetLastWriteStatus() => _lastWriteStatus;
514544
public static DateTime GetLastWriteTime() => _lastWriteTime;
515-
516-
517-
}
545+
}

logs/log.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2025-06-02T11:37:01.9354966Z [INFO] ({TcpListenerService}) TCP Listener started
2+
2025-06-02T11:44:10.8180667Z [INFO] (Client IP: 192.168.0.4) Valid Message
3+
2025-06-02T11:44:10.9363659Z [INFO] (Client IP: 192.168.0.4) Valid Message
4+
2025-06-02T11:44:11.0588563Z [INFO] (Client IP: 192.168.0.4) Valid Message
5+
2025-06-02T11:44:11.1634125Z [INFO] (Client IP: 192.168.0.4) Valid Message
6+
2025-06-02T11:44:11.2901213Z [INFO] (Client IP: 192.168.0.4) Valid Message
7+
2025-06-02T11:44:42.3011218Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
8+
2025-06-02T11:44:45.4835805Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
9+
2025-06-02T11:44:45.5885142Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
10+
2025-06-02T11:44:45.6933153Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
11+
2025-06-02T11:44:45.8079390Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
12+
2025-06-02T11:44:45.9113191Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
13+
2025-06-02T11:44:46.0142659Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
14+
2025-06-02T11:44:46.1181041Z [WARNING] (Client IP: 192.168.0.4) INVALID MESSAGE
15+
2025-06-02T11:44:49.3325242Z [WARNING] (Client IP: 192.168.0.4) MALICIOUS INPUT
16+
2025-06-02T11:44:52.3055711Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
17+
2025-06-02T11:45:02.3123612Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
18+
2025-06-02T11:45:12.3240028Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
19+
2025-06-02T11:45:22.3317623Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
20+
2025-06-02T11:45:32.3447151Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
21+
2025-06-02T11:45:42.3576305Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
22+
2025-06-02T11:45:52.3700921Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
23+
2025-06-02T11:46:02.3848431Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
24+
2025-06-02T11:46:12.3998366Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
25+
2025-06-02T11:46:21.5473973Z [INFO] (🟡 TCP server is shutting down due to cancellation request.) TCP Listener Cancellation requested
26+
2025-06-02T11:46:21.5483554Z [INFO] (🔌 TCP listener stopped.) TCP Listener stopped
27+
2025-06-02T11:46:29.6426760Z [INFO] ({TcpListenerService}) TCP Listener started
28+
2025-06-02T11:46:44.8089055Z [INFO] (Client IP: 192.168.0.4) Valid Message
29+
2025-06-02T11:46:44.9361360Z [INFO] (Client IP: 192.168.0.4) Valid Message
30+
2025-06-02T11:46:45.0598483Z [INFO] (Client IP: 192.168.0.4) Valid Message
31+
2025-06-02T11:46:45.1844935Z [INFO] (Client IP: 192.168.0.4) Valid Message
32+
2025-06-02T11:47:19.7039568Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
33+
2025-06-02T11:47:29.7086890Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
34+
2025-06-02T11:47:39.7233111Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
35+
2025-06-02T11:47:49.7348278Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
36+
2025-06-02T11:47:59.7438548Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
37+
2025-06-02T11:48:09.7479463Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
38+
2025-06-02T11:48:19.7536560Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
39+
2025-06-02T11:48:29.7615115Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
40+
2025-06-02T11:48:39.7669010Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
41+
2025-06-02T11:48:49.7724930Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
42+
2025-06-02T11:48:59.7880087Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
43+
2025-06-02T11:49:09.7936711Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
44+
2025-06-02T11:49:19.8010347Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
45+
2025-06-02T11:49:29.8167239Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
46+
2025-06-02T11:49:39.8314098Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
47+
2025-06-02T11:49:49.8472988Z [WARNING] (⚠️ No USB drive detected.) No USB Drive detected.
48+
2025-06-02T11:50:00.4198007Z [INFO] (Data Saved to D:\LabData.json) Data Saved.
49+
2025-06-02T11:52:55.8212770Z [INFO] (🟡 TCP server is shutting down due to cancellation request.) TCP Listener Cancellation requested
50+
2025-06-02T11:52:55.8224596Z [INFO] (🔌 TCP listener stopped.) TCP Listener stopped
51+
2025-06-02T11:52:59.8444850Z [INFO] ({TcpListenerService}) TCP Listener started

tests/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import time
44
import random
55

6-
SERVER_IP = "192.168.0.5"
6+
SERVER_IP = "192.168.0.4"
77
SERVER_PORT = 12377
88

99
TESTS = [

0 commit comments

Comments
 (0)