1+ using System . Net . Http . Json ;
12using System . Net . NetworkInformation ;
23using System . Net . Sockets ;
34using System . Reflection ;
5+ using System . Text . Json ;
46using LogMkCommon ;
57
68namespace LogMkAgent . Services ;
@@ -17,8 +19,13 @@ public class AgentRegistrationService : BackgroundService
1719 private readonly LogWatcher _logWatcher ;
1820 private readonly ILogger < AgentRegistrationService > _logger ;
1921
20- private readonly TimeSpan _heartbeatInterval = TimeSpan . FromSeconds ( 30 ) ;
21- private readonly TimeSpan _configPollInterval = TimeSpan . FromSeconds ( 60 ) ;
22+ private readonly TimeSpan _heartbeatInterval = TimeSpan . FromSeconds ( 60 ) ;
23+
24+ private static readonly JsonSerializerOptions _jsonOptions = new ( )
25+ {
26+ TypeInfoResolver = new ApiJsonSerializerContext ( ) ,
27+ PropertyNameCaseInsensitive = true
28+ } ;
2229
2330 private readonly DateTime _startedAt = DateTime . UtcNow ;
2431 private readonly string _agentId ;
@@ -42,48 +49,45 @@ public AgentRegistrationService(
4249 _version = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ? . ToString ( ) ;
4350 _ipAddress = TryGetLocalIp ( ) ;
4451
52+ // Stamp every outgoing log line with this agent's id so the API/UI
53+ // can show which node a log came from.
54+ _batchingService . AgentId = _agentId ;
55+
4556 _logger . LogInformation ( "AgentRegistrationService starting: AgentId={AgentId}, Hostname={Hostname}, Version={Version}" ,
4657 _agentId , _hostname , _version ) ;
4758 }
4859
4960 protected override async Task ExecuteAsync ( CancellationToken stoppingToken )
5061 {
51- // Pull config once on startup before the regular polling loop
52- await PullConfigAsync ( stoppingToken ) . ConfigureAwait ( false ) ;
53-
54- var lastConfigPull = DateTime . UtcNow ;
62+ // Send an initial heartbeat right away so the agent's config is applied
63+ // before the first batch is processed.
64+ try
65+ {
66+ await SendHeartbeatAsync ( stoppingToken ) . ConfigureAwait ( false ) ;
67+ }
68+ catch ( Exception ex )
69+ {
70+ _logger . LogWarning ( ex , "Initial heartbeat failed" ) ;
71+ }
5572
5673 while ( ! stoppingToken . IsCancellationRequested )
5774 {
5875 try
5976 {
60- await SendHeartbeatAsync ( stoppingToken ) . ConfigureAwait ( false ) ;
61- }
62- catch ( Exception ex )
63- {
64- _logger . LogWarning ( ex , "Heartbeat failed" ) ;
77+ await Task . Delay ( _heartbeatInterval , stoppingToken ) . ConfigureAwait ( false ) ;
6578 }
66-
67- if ( DateTime . UtcNow - lastConfigPull >= _configPollInterval )
79+ catch ( OperationCanceledException )
6880 {
69- try
70- {
71- await PullConfigAsync ( stoppingToken ) . ConfigureAwait ( false ) ;
72- lastConfigPull = DateTime . UtcNow ;
73- }
74- catch ( Exception ex )
75- {
76- _logger . LogWarning ( ex , "Config pull failed" ) ;
77- }
81+ break ;
7882 }
7983
8084 try
8185 {
82- await Task . Delay ( _heartbeatInterval , stoppingToken ) . ConfigureAwait ( false ) ;
86+ await SendHeartbeatAsync ( stoppingToken ) . ConfigureAwait ( false ) ;
8387 }
84- catch ( OperationCanceledException )
88+ catch ( Exception ex )
8589 {
86- break ;
90+ _logger . LogWarning ( ex , "Heartbeat failed" ) ;
8791 }
8892 }
8993 }
@@ -113,28 +117,24 @@ private async Task SendHeartbeatAsync(CancellationToken cancellationToken)
113117 if ( ! response . IsSuccessStatusCode )
114118 {
115119 _logger . LogDebug ( "Heartbeat returned non-success status {StatusCode}" , response . StatusCode ) ;
120+ return ;
116121 }
117- }
118122
119- private async Task PullConfigAsync ( CancellationToken cancellationToken )
120- {
121123 try
122124 {
123- var config = await _apiClient . GetDataAsync < AgentConfig > ( $ "api/agents/{ Uri . EscapeDataString ( _agentId ) } /config")
124- . ConfigureAwait ( false ) ;
125+ var payload = await response . Content
126+ . ReadFromJsonAsync < HeartbeatResponse > ( _jsonOptions , cancellationToken )
127+ . ConfigureAwait ( false ) ;
125128
126- if ( config = = null )
129+ if ( payload ? . Config ! = null )
127130 {
128- _logger . LogDebug ( "No agent config returned for {AgentId}" , _agentId ) ;
129- return ;
131+ _logWatcher . ApplyConfig ( payload . Config ) ;
132+ _batchingService . ApplyConfig ( payload . Config ) ;
130133 }
131-
132- _logWatcher . ApplyConfig ( config ) ;
133- _batchingService . ApplyConfig ( config ) ;
134134 }
135- catch ( HttpRequestException ex )
135+ catch ( Exception ex )
136136 {
137- _logger . LogDebug ( ex , "Could not reach API to pull config " ) ;
137+ _logger . LogDebug ( ex , "Failed to parse heartbeat response " ) ;
138138 }
139139 }
140140
0 commit comments