fix: accept logs from unregistered agents using JWT claims
After server restart, agents send logs before re-registering. Instead of dropping these logs, fall back to application and environment from the JWT token claims. Only drops logs when neither registry nor JWT provide an applicationId. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,15 +2,18 @@ package com.cameleer3.server.app.controller;
|
||||
|
||||
import com.cameleer3.common.model.LogEntry;
|
||||
import com.cameleer3.server.app.metrics.ServerMetrics;
|
||||
import com.cameleer3.server.app.security.JwtAuthenticationFilter;
|
||||
import com.cameleer3.server.core.ingestion.BufferedLogEntry;
|
||||
import java.util.List;
|
||||
import com.cameleer3.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer3.server.core.agent.AgentInfo;
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer3.server.core.security.JwtService.JwtValidationResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.cameleer3.server.app.config.TenantProperties;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -49,7 +52,8 @@ public class LogIngestionController {
|
||||
@Operation(summary = "Ingest application log entries",
|
||||
description = "Accepts a batch of log entries from an agent. Entries are buffered and flushed periodically.")
|
||||
@ApiResponse(responseCode = "202", description = "Logs accepted for indexing")
|
||||
public ResponseEntity<Void> ingestLogs(@RequestBody List<LogEntry> entries) {
|
||||
public ResponseEntity<Void> ingestLogs(@RequestBody List<LogEntry> entries,
|
||||
HttpServletRequest request) {
|
||||
String instanceId = extractAgentId();
|
||||
if (instanceId == null || instanceId.isBlank()) {
|
||||
log.warn("Log ingestion rejected: no agent identity in request (unauthenticated or missing principal)");
|
||||
@@ -62,19 +66,28 @@ public class LogIngestionController {
|
||||
return ResponseEntity.accepted().build();
|
||||
}
|
||||
|
||||
String applicationId;
|
||||
String environment;
|
||||
|
||||
AgentInfo agent = registryService.findById(instanceId);
|
||||
if (agent == null) {
|
||||
log.warn("Log ingestion from instance={}: agent not found in registry (not registered or expired). {} entries dropped.",
|
||||
instanceId, entries.size());
|
||||
serverMetrics.recordIngestionDrops("no_agent", entries.size());
|
||||
return ResponseEntity.accepted().build();
|
||||
if (agent != null) {
|
||||
applicationId = agent.applicationId();
|
||||
environment = agent.environmentId() != null ? agent.environmentId() : "default";
|
||||
} else {
|
||||
// Agent not yet in registry (e.g. server just restarted) — fall back to JWT claims
|
||||
JwtValidationResult jwt = (JwtValidationResult) request.getAttribute(JwtAuthenticationFilter.JWT_RESULT_ATTR);
|
||||
applicationId = jwt != null ? jwt.application() : null;
|
||||
environment = jwt != null && jwt.environment() != null ? jwt.environment() : "default";
|
||||
if (applicationId != null) {
|
||||
log.debug("Log ingestion from instance={}: agent not in registry, using JWT claims (app={}, env={})",
|
||||
instanceId, applicationId, environment);
|
||||
}
|
||||
}
|
||||
|
||||
String applicationId = agent.applicationId();
|
||||
String environment = agent.environmentId() != null ? agent.environmentId() : "default";
|
||||
|
||||
if (applicationId == null || applicationId.isBlank()) {
|
||||
log.warn("Log ingestion from instance={}: agent has no applicationId. {} entries dropped.", instanceId, entries.size());
|
||||
log.warn("Log ingestion from instance={}: no applicationId from registry or JWT. {} entries dropped.",
|
||||
instanceId, entries.size());
|
||||
serverMetrics.recordIngestionDrops("no_agent", entries.size());
|
||||
return ResponseEntity.accepted().build();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user