use of com.peterphi.std.guice.common.logging.logreport.LogLine in project stdlib by petergeneric.
the class ServiceManagerLogForwardDaemon method forwardLogs.
private int forwardLogs(LinkedList<LogLine> source) {
if (!registered)
// cannot forward logs, not yet registered!
return 0;
// Take a page of logs from the incoming stream
final LogLine[] array;
synchronized (source) {
array = new LogLine[Math.min(pageSize, source.size())];
for (int i = 0; i < array.length; i++) array[i] = source.poll();
}
// Forward to the network log receiver
try {
LogReport report = new LogReport();
report.setServiceId(instanceId);
report.setLines(array);
logService.report(report);
// return the number of lines forwarded
return array.length;
} catch (Throwable t) {
// Put the logs that we failed to send back into the queue again
synchronized (source) {
source.addAll(0, Arrays.asList(array));
}
// N.B. we don't use log4j here because the logs will just grow the backlog of messages if there's a permanent problem
log.warn("Service Manager Logging failed to send logs to the network receiver", t);
// 0 lines forwarded
return 0;
}
}
use of com.peterphi.std.guice.common.logging.logreport.LogLine in project stdlib by petergeneric.
the class ServiceManagerLogForwardDaemon method linesDeletedMessage.
private LogLine linesDeletedMessage(LogLine first, LogLine last, int linesDeleted) {
LogLine line = new LogLine();
line.setCategory("SYSTEM");
line.setLevel(ServiceManagerAppender.LEVEL_FATAL);
// Backdate this log message
line.setWhen(first.getWhen());
line.setMessage("Messages are missing - logging system hit transmission queue limit (" + maxBacklog + ") at " + new DateTime() + " so deleted " + linesDeleted + " lines covering " + new DateTime(first.getWhen()) + " to " + new DateTime(last.getWhen()));
return line;
}
use of com.peterphi.std.guice.common.logging.logreport.LogLine in project stdlib by petergeneric.
the class ServiceManagerLogForwardDaemon method deleteMessageBacklog.
/**
*/
private void deleteMessageBacklog() {
synchronized (incoming) {
// Keep track of the first and last log message deleted
final LogLine first = incoming.poll();
LogLine last = first;
int linesDeleted = 1;
// Cut the backlog down to a third of the max backlog
while (incoming.size() >= (maxBacklog / 3)) {
last = incoming.poll();
linesDeleted++;
}
// Insert the "lines were deleted" log message in their place
incoming.add(0, linesDeletedMessage(first, last, linesDeleted));
}
}
use of com.peterphi.std.guice.common.logging.logreport.LogLine in project stdlib by petergeneric.
the class ServiceManagerLoggingRestServiceImpl method report.
@Override
public void report(final LogReport logs) {
if (log.isTraceEnabled())
log.trace("Received " + logs.getLines().length + " log lines to store");
try {
final ServiceInstanceEntity serviceInstance = cache.get(logs.getServiceId());
// Make sure that all store calls are for the same partition (date + instance id)
// This is technically only a requirement for Azure but it's a guarantee other
// stores can use effectively (e.g. writing to datestamped log files)
String partitionKey = null;
List<LogLineTableEntity> pending = new ArrayList<>();
for (LogLine line : logs.getLines()) {
LogLineTableEntity entity = convert(serviceInstance, line);
if (partitionKey == null) {
// First entry in a new partition
partitionKey = entity.getPartitionKey();
} else if (!partitionKey.equals(entity.getPartitionKey())) {
// Flush all the lines up til now and then start a new list
service.store(pending);
pending = new ArrayList<>();
partitionKey = entity.getPartitionKey();
}
pending.add(entity);
}
// Make sure we flush any remaining data to the storage system
service.store(pending);
} catch (Throwable t) {
log.error("Error saving logs", t);
throw t;
}
}
use of com.peterphi.std.guice.common.logging.logreport.LogLine in project stdlib by petergeneric.
the class ServiceManagerAppender method append.
@Override
protected void append(final LoggingEvent event) {
LogLine line = new LogLine();
line.setMessage(event.getRenderedMessage());
line.setWhen(event.getTimeStamp());
final String traceId = Tracing.getTraceId();
if (traceId != null)
line.setTraceId(traceId);
{
final int lastDot = event.getLoggerName().lastIndexOf('.');
if (lastDot == -1)
// no dot in name
line.setCategory(event.getLoggerName());
else
line.setCategory(event.getLoggerName().substring(lastDot + 1));
}
final String requestUri = (String) event.getMDC(TracingConstants.MDC_HTTP_REQUEST_URI);
// because it will be a member of a threadpool
if (requestUri == null)
line.setThread(event.getThreadName());
// Conditionally log the request URI
if (requestUri != null && (LOG_REQUEST_URI_AT_ALL_LEVELS || line.getLevel() >= LEVEL_WARN || event.getThrowableInformation() != null))
line.setRequestUri(requestUri);
// Log the user id (if known)
final String userId = (String) event.getMDC(TracingConstants.MDC_USER_ID);
if (userId != null)
line.setUserId(userId);
line.setLevel(level(event.getLevel()));
if (event.getThrowableInformation() != null) {
appendThrowableInfo(line, event.getThrowableInformation());
}
if (LOG_SUBSCRIBER != null)
LOG_SUBSCRIBER.accept(line);
}
Aggregations