Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NR-163715 Critical error logging via LogMessage event #139

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.newrelic.agent.security.intcodeagent.models.javaagent.ExitEventBean;
import com.newrelic.agent.security.intcodeagent.models.javaagent.JavaAgentEventBean;
import com.newrelic.agent.security.intcodeagent.websocket.EventSendPool;
import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.*;
Expand Down Expand Up @@ -49,6 +50,7 @@ public class Dispatcher implements Callable {

public static final String SEPARATOR1 = ", ";
public static final String APP_LOCATION = "app-location";
public static final String UNABLE_TO_CONVERT_OPERATION_TO_EVENT = "Unable to convert operation to event: %s, %s, %s";
private ExitEventBean exitEventBean;
private AbstractOperation operation;
private SecurityMetaData securityMetaData;
Expand Down Expand Up @@ -221,7 +223,8 @@ public Object call() throws Exception {
}
// detectDeployedApplication();
} catch (Throwable e) {
e.printStackTrace();
logger.postLogMessageIfNecessary(LogLevel.WARNING, String.format(UNABLE_TO_CONVERT_OPERATION_TO_EVENT, operation.getApiID(), operation.getSourceMethod(), JsonConverter.getObjectMapper().writeValueAsString(operation.getUserClassEntity())), e,
this.getClass().getName());
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.newrelic.agent.security.instrumentator.httpclient;

import com.newrelic.agent.security.AgentInfo;
import com.newrelic.agent.security.intcodeagent.executor.CustomFutureTask;
import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool;
import com.newrelic.agent.security.intcodeagent.filelogging.LogLevel;
import com.newrelic.agent.security.intcodeagent.models.IASTDataTransferRequest;
import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter;
import com.newrelic.agent.security.intcodeagent.websocket.WSClient;
import com.newrelic.agent.security.intcodeagent.websocket.WSUtils;
import com.newrelic.agent.security.util.AgentUsageMetric;
Expand Down Expand Up @@ -85,6 +84,7 @@ private void task() {
} catch (Throwable e) {
logger.log(LogLevel.SEVERE, String.format(UNABLE_TO_SEND_IAST_DATA_REQUEST_DUE_TO_ERROR_S_S, e.toString(), e.getCause().toString()), this.getClass().getName());
logger.log(LogLevel.FINEST, String.format(UNABLE_TO_SEND_IAST_DATA_REQUEST_DUE_TO_ERROR, request), e, this.getClass().getName());
logger.postLogMessageIfNecessary(LogLevel.SEVERE, String.format(UNABLE_TO_SEND_IAST_DATA_REQUEST_DUE_TO_ERROR, JsonConverter.toJSON(request)), e, this.getClass().getName());
}
}

Expand Down Expand Up @@ -125,9 +125,7 @@ public void startDataRequestSchedule(long delay, TimeUnit timeUnit){
try {
stopDataRequestSchedule(true);
future = executorService.scheduleWithFixedDelay(this::task, 0, delay, timeUnit);
} catch (Throwable e){
e.printStackTrace();
}
} catch (Throwable ignored){}
}

public void stopDataRequestSchedule(boolean force){
Expand All @@ -136,9 +134,7 @@ public void stopDataRequestSchedule(boolean force){
future.cancel(force);
future = null;
}
} catch (Throwable e) {
e.printStackTrace();
}
} catch (Throwable ignored) {}
}

public void setCooldownTillTimestamp(long timestamp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public OkHttpClient getClient() {
return clientThreadLocal.get();
}

public void fireRequest(Request request, int repeatCount) {
public void fireRequest(Request request, int repeatCount, String fuzzRequestId) {
OkHttpClient client = clientThreadLocal.get();

logger.log(LogLevel.FINER, String.format(FIRING_REQUEST_METHOD_S, request.method()), RestClient.class.getName());
Expand All @@ -131,10 +131,15 @@ public void fireRequest(Request request, int repeatCount) {
}
} catch (InterruptedIOException e){
if(repeatCount >= 0){
fireRequest(request, --repeatCount);
fireRequest(request, --repeatCount, fuzzRequestId);
}
} catch (IOException e) {
logger.log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, request), e, RestClient.class.getName());
logger.postLogMessageIfNecessary(LogLevel.WARNING,
String.format(CALL_FAILED_REQUEST_S_REASON, fuzzRequestId),
e, RestRequestProcessor.class.getName());

// TODO: Add to fuzz fail count in HC and remove FuzzFailEvent if not needed.
FuzzFailEvent fuzzFailEvent = new FuzzFailEvent(AgentInfo.getInstance().getApplicationUUID());
fuzzFailEvent.setFuzzHeader(request.header(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID));
EventSendPool.getInstance().sendEvent(fuzzFailEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.newrelic.agent.security.intcodeagent.models.javaagent.IntCodeControlCommand;
import com.newrelic.agent.security.intcodeagent.websocket.WSUtils;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper;
import okhttp3.Request;
import org.apache.commons.lang3.StringUtils;

Expand Down Expand Up @@ -68,19 +67,21 @@ public Boolean call() throws InterruptedException {
RestRequestThreadPool.getInstance().removeFromProcessedCC(controlCommand.getId());
Request request = RequestUtils.generateK2Request(httpRequest);
if(request != null) {
RestClient.getInstance().fireRequest(request, repeatCount);
RestClient.getInstance().fireRequest(request, repeatCount, controlCommand.getId());
}
return true;
} catch (JsonProcessingException e){
logger.log(LogLevel.SEVERE,
String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0)),
e, RestRequestProcessor.class.getName());
logger.postLogMessageIfNecessary(LogLevel.SEVERE,
String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getId()), e, RestRequestProcessor.class.getName());
} catch (Throwable e) {
logger.log(LogLevel.SEVERE,
String.format(ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0)),
e, RestRequestProcessor.class.getName());
logger.postLogMessageIfNecessary(LogLevel.SEVERE,
String.format(ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0)),
String.format(ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getId()),
e, RestRequestProcessor.class.getName());
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ public static String getPodId() {
podId = StringUtils.substringBetween(line, "kubepods-besteffort-pod", ".slice");
}
}
} catch (Throwable e) {
e.printStackTrace();
}
} catch (Throwable ignored) {}
return StringUtils.replaceChars(podId, "_", "-");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class ControlCommandProcessor implements Runnable {
public static final String UPDATED_POLICY_FAILED_VALIDATION_REVERTING_TO_DEFAULT_POLICY_FOR_THE_MODE = "Updated policy failed validation. Reverting to default policy for the mode";
public static final String ERROR_WHILE_PROCESSING_RECONNECTION_CC_S_S = "Error while processing reconnection CC : %s : %s";
public static final String ERROR_WHILE_PROCESSING_RECONNECTION_CC = "Error while processing reconnection CC :";
public static final String ERROR_WHILE_PROCESSING_RECONNECTION_CC_ID = "Error while processing reconnection CC : %s";

public static final String UNABLE_TO_PARSE_RECEIVED_DEFAULT_POLICY = "Unable to parse received default policy : ";
public static final String ERROR_IN_CONTROL_COMMAND_PROCESSOR = "Error in controlCommandProcessor : ";
public static final String ARGUMENTS = "arguments";
Expand Down Expand Up @@ -95,6 +97,10 @@ public void run() {
} catch (Throwable e) {
logger.log(LogLevel.SEVERE, ERROR_IN_CONTROL_COMMAND_PROCESSOR, e,
ControlCommandProcessor.class.getSimpleName());

logger.postLogMessageIfNecessary(LogLevel.WARNING,
ERROR_IN_CONTROL_COMMAND_PROCESSOR,
e, this.getClass().getName());
return;
}

Expand Down Expand Up @@ -232,6 +238,8 @@ public void run() {
} catch (Throwable e) {
logger.log(LogLevel.SEVERE, String.format(ERROR_WHILE_PROCESSING_RECONNECTION_CC_S_S, e.getMessage(), e.getCause()), this.getClass().getName());
logger.log(LogLevel.SEVERE, ERROR_WHILE_PROCESSING_RECONNECTION_CC, e, this.getClass().getName());
logger.postLogMessageIfNecessary(LogLevel.SEVERE, String.format(ERROR_WHILE_PROCESSING_RECONNECTION_CC_ID, controlCommand.getId()), e,
this.getClass().getName());
}
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

public class ControlCommandProcessorThreadPool {

public static final String UNEXPECTED_ERROR_WHILE_PROCESSING_CONTROL_COMMAND = "Unexpected error while processing control command";
/**
* Thread pool executor.
*/
Expand Down Expand Up @@ -70,6 +71,8 @@ protected void afterExecute(Runnable r, Throwable t) {
future.get();
}
} catch (Throwable e) {
logger.postLogMessageIfNecessary(LogLevel.WARNING, UNEXPECTED_ERROR_WHILE_PROCESSING_CONTROL_COMMAND, e,
this.getClass().getName());
}
}
super.afterExecute(r, t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ protected void afterExecute(Runnable r, Throwable t) {
if (future.isDone()) {
future.get();
}
} catch (Throwable e) {
}
} catch (Throwable ignored) {}
}
super.afterExecute(r, t);
}
Expand Down Expand Up @@ -165,8 +164,8 @@ public void postLogMessageIfNecessary(LogLevel logLevel, String event, Throwable
postLogMessage(logLevel, event, exception, caller);
}

private LogMessage postLogMessage(LogLevel logLevel, String event, Throwable exception, String caller) {
LogMessage message = new LogMessage(logLevel.name(), event, caller, exception, AgentInfo.getInstance().getLinkingMetadata());
private LogMessage postLogMessage(LogLevel logLevel, String messageString, Throwable exception, String caller) {
LogMessage message = new LogMessage(logLevel.name(), messageString, caller, exception, AgentInfo.getInstance().getLinkingMetadata());
if (logLevel.getLevel() <= LogLevel.WARNING.getLevel()) {
AgentUtils.getInstance().getStatusLogMostRecentErrors().add(JsonConverter.toJSON(message));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ private static void createLogFile() {
writer.write(String.format(LOG_CONFIGURED_SUCCESSFULLY_MSG, LogLevel.getLevelName(defaultLogLevel), maxFileSize));
writer.flush();
} catch (Throwable e) {
//TODO report to cloud
FileLoggerThreadPool.getInstance().setInitLoggingActive(false);

String tmpDir = System.getProperty("java.io.tmpdir");
System.err.println("[NR-CSEC-JA] Unable to create status log file!!! Please find the error in " + tmpDir + File.separator + "NR-CSEC-Logger.err");
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ private static boolean createLogFile() {

} catch (Throwable e) {
if (FileLoggerThreadPool.getInstance().isLoggingActive()) {
//TODO report to cloud
FileLoggerThreadPool.getInstance().setLoggingActive(false);
}
String tmpDir = System.getProperty("java.io.tmpdir");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class LogMessage {

private String jsonName = "log-message";
private String jsonName = "critical-messages";

private String applicationUUID = AgentInfo.getInstance().getApplicationUUID();

Expand All @@ -25,6 +25,8 @@ public class LogMessage {

private Map<String, String> linkingMetadata;

private String threadName;

public LogMessage(String level, String message, String caller, Throwable exception, Map<String, String> linkingMetadata) {
this.timestamp = Instant.now().toEpochMilli();
this.level = level;
Expand All @@ -34,6 +36,7 @@ public LogMessage(String level, String message, String caller, Throwable excepti
if (exception != null) {
this.exception = new LogMessageException(exception, 0, 1);
}
this.threadName = Thread.currentThread().getName();
}

public Long getTimestamp() {
Expand Down Expand Up @@ -77,6 +80,15 @@ public void setApplicationUUID(String applicationUUID) {
this.applicationUUID = applicationUUID;
}


public String getThreadName() {
return threadName;
}

public void setThreadName(String threadName) {
this.threadName = threadName;
}

@Override
public String toString() {
return JsonConverter.toJSON(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class LogMessageException {

private String type;

private String message;

private LogMessageException cause;

private String[] stackTrace;

public LogMessageException(Throwable exception, int nestingLevel, int maxNestingLevel) {
this.type = exception.getClass().getName();
this.message = exception.getMessage();
StackTraceElement[] trace = exception.getStackTrace();
this.stackTrace = new String[trace.length];
Expand All @@ -37,6 +40,10 @@ public String[] getStackTrace() {
return stackTrace;
}

public String getType() {
return type;
}

public String toString() {
return JsonConverter.toJSON(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,28 @@
import com.fasterxml.jackson.dataformat.javaprop.JavaPropsMapper;
import com.newrelic.agent.security.AgentConfig;
import com.newrelic.agent.security.AgentInfo;
import com.newrelic.agent.security.instrumentator.dispatcher.Dispatcher;
import com.newrelic.agent.security.instrumentator.dispatcher.DispatcherPool;
import com.newrelic.agent.security.instrumentator.httpclient.RestRequestThreadPool;
import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance;
import com.newrelic.agent.security.instrumentator.utils.AgentUtils;
import com.newrelic.agent.security.instrumentator.utils.ApplicationInfoUtils;
import com.newrelic.agent.security.instrumentator.utils.CollectorConfigurationUtils;
import com.newrelic.agent.security.instrumentator.utils.ExecutionIDGenerator;
import com.newrelic.agent.security.instrumentator.utils.HashGenerator;
import com.newrelic.agent.security.instrumentator.utils.INRSettingsKey;
import com.newrelic.agent.security.instrumentator.utils.*;
import com.newrelic.agent.security.intcodeagent.constants.AgentServices;
import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool;
import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper;
import com.newrelic.agent.security.intcodeagent.filelogging.LogLevel;
import com.newrelic.agent.security.intcodeagent.logging.HealthCheckScheduleThread;
import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants;
import com.newrelic.agent.security.intcodeagent.models.javaagent.ApplicationURLMappings;
import com.newrelic.agent.security.intcodeagent.models.javaagent.ExitEventBean;
import com.newrelic.agent.security.intcodeagent.properties.BuildInfo;
import com.newrelic.agent.security.intcodeagent.schedulers.FileCleaner;
import com.newrelic.agent.security.intcodeagent.schedulers.SchedulerHelper;
import com.newrelic.agent.security.intcodeagent.utils.CommonUtils;
import com.newrelic.agent.security.intcodeagent.websocket.*;
import com.newrelic.agent.security.intcodeagent.websocket.EventSendPool;
import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter;
import com.newrelic.agent.security.intcodeagent.websocket.WSClient;
import com.newrelic.agent.security.intcodeagent.websocket.WSReconnectionST;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Transaction;
import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.AgentMetaData;
import com.newrelic.api.agent.security.schema.ApplicationURLMapping;
import com.newrelic.api.agent.security.schema.HttpRequest;
import com.newrelic.api.agent.security.schema.K2RequestIdentifier;
import com.newrelic.api.agent.security.schema.SecurityMetaData;
import com.newrelic.api.agent.security.schema.UserClassEntity;
import com.newrelic.api.agent.security.schema.VulnerabilityCaseType;
import com.newrelic.api.agent.security.schema.*;
import com.newrelic.api.agent.security.schema.operation.RXSSOperation;
import com.newrelic.api.agent.security.schema.policy.AgentPolicy;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -53,10 +40,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;

import static com.newrelic.agent.security.intcodeagent.logging.IAgentConstants.AGENT_INIT_LOG_STEP_FIVE_END;
import static com.newrelic.agent.security.intcodeagent.logging.IAgentConstants.COM_SUN;
import static com.newrelic.agent.security.intcodeagent.logging.IAgentConstants.STARTED_MODULE_LOG;
import static com.newrelic.agent.security.intcodeagent.logging.IAgentConstants.SUN_REFLECT;
import static com.newrelic.agent.security.intcodeagent.logging.IAgentConstants.*;

public class Agent implements SecurityAgent {

Expand Down Expand Up @@ -170,6 +154,9 @@ private BuildInfo readCollectorBuildInfo() {
readValue(CommonUtils.getResourceStreamFromAgentJar("Agent.properties"), BuildInfo.class);
} catch (Throwable e) {
logger.log(LogLevel.SEVERE, String.format(CRITICAL_ERROR_UNABLE_TO_READ_BUILD_INFO_AND_VERSION_S_S, e.getMessage(), e.getCause()), this.getClass().getName());
logger.postLogMessageIfNecessary(LogLevel.SEVERE,
String.format(CRITICAL_ERROR_UNABLE_TO_READ_BUILD_INFO_AND_VERSION_S_S, e.getMessage(), e.getCause()),
e, this.getClass().getName());
logger.log(LogLevel.FINER, CRITICAL_ERROR_UNABLE_TO_READ_BUILD_INFO_AND_VERSION, e, this.getClass().getName());
}
return buildInfo;
Expand Down Expand Up @@ -453,9 +440,7 @@ public SecurityMetaData getSecurityMetaData() {
return (SecurityMetaData) meta;
}
}
} catch (Throwable e) {
// e.printStackTrace();
}
} catch (Throwable ignored) {}
return new SecurityMetaData();
}

Expand Down
Loading