Allow changing the logging level on the LogEntryLevelBuilder
TrangOul opened this issue · comments
New Feature Summary
Please make it possible to set the logging level after the LogEntryLevelBuilder
instance is created, just like with setRecord
or setHttpResponseDetails
.
Example usage:
Current:
HttpRequest request = new HttpRequest();
HttpResponse response = new Http().send(request);
if (isSuccess(request)) { // 200 <= statusCode < 300;
Logger.debug(logTitle).setHttpRequestDetails(request).setHttpResponseDetails(response).addTag(LogUtils.TAG_CALLOUT);
} else {
// all the code repeated except different logging level
Logger.error(logTitle).setHttpRequestDetails(request).setHttpResponseDetails(response).addTag(LogUtils.TAG_CALLOUT);
}
Attempt to avoid repeating logging:
HttpRequest request = new HttpRequest();
LogEntryEventBuilder logBuilder = Logger.debug(logTitle).setHttpRequestDetails(request).addTag(LogUtils.TAG_CALLOUT);
HttpResponse response = new Http().send(request);
logBuilder.setHttpResponseDetails(this.response); //so far, so good; setting response as an additional detail
if (!isSuccess(request)) {
// logBuilder.setLoggingLevel(System.LoggingLevel.ERROR); // impossible, no such method
Logger.flushBuffer(); // remove previous success log - and possibly other unsaved logs...
Logger.error(logTitle).setHttpRequestDetails(request).setHttpResponseDetails(response).addTag(LogUtils.TAG_CALLOUT); // again, repeated code
}
Currently the entryLoggingLevel
field in the LogEntryLevelBuilder
class is final
, so there is no such a setLoggingLevel
method.. Is there any reason why?
Hi @TrangOul - there would be some downstream complications with allowing the logging level to be changed after the builder is created. The entry's logging level is used to decide if the builder is added to Logger
's buffer & to decide if the method calls in the builder should actually do anything. When the entry logging level doesn't match the user's configured logging level (e.g., the user has logging level INFO
, but the entry has FINE
), all of the builder methods are essentially no-ops to minimize CPU time - if the logging level then changed later, the builder wouldn't have all of the necessary info set on the LogEntryEvent__e
record.
I think you can accomplish your goal in a slightly different way, using an existing method in Logger
- Logger.newEntry()
. This method takes LoggingLevel
enum value as the first parameter, so you can do something like this to minimize repeating your code:
HttpRequest request = new HttpRequest();
HttpResponse response = new Http().send(request);
LoggingLevel entryLoggingLevel = isSuccess(request) ? LoggingLevel.DEBUG : LoggingLevel.ERROR;
Logger.newEntry(entryLoggingLevel, logTitle).setHttpRequestDetails(request).setHttpResponseDetails(response).addTag(LogUtils.TAG_CALLOUT);
Let me know if this approach handles your situation.
That's a nice approach, thanks!
Actually I need to catch two possible errors: errors from callout (response ≠ 200) and Apex exceptions.
Here is the old code, which saved two log entries:
try {
HttpRequest request = new HttpRequest();
LogEntryEventBuilder logBuilder = Logger.debug(buildTitle(...)).setHttpRequestDetails(request).addTag(LogUtils.TAG_CALLOUT);
HttpResponse response = new Http().send(request);
logBuilder.setHttpResponseDetails(this.response);
if (!isSuccess(request)) {
Logger.flushBuffer(); // remove previous success log
logBuilder = Logger.error(logTitle).setHttpRequestDetails(this.request).setHttpResponseDetails(this.response).addTag(LogUtils.TAG_CALLOUT);
}
} catch (Exception e) {
Logger.error(e.getMessage()).setExceptionDetails(e).addTag(LogUtils.TAG_EXCEPTION);
throw e;
} finally {
Logger.saveLog();
}
And new code, with a single entry per callout, with all possible details (request, response, exception):
HttpRequest request; // actually these are instance variables,
HttpResponse response; // but for the sake of a minimal example
LoggingLevel entryLoggingLevel = LoggingLevel.DEBUG;
Exception ex;
try {
request = new HttpRequest();
response = new Http().send(request);
if (!isSuccess(response)) {
entryLoggingLevel = LoggingLevel.ERROR;
}
} catch (Exception e) {
entryLoggingLevel = LoggingLevel.ERROR;
ex = e;
throw e;
} finally {
LogEntryEventBuilder logBuilder = Logger.newEntry(entryLoggingLevel, buildTitle(...))
.setHttpRequestDetails(request)
.setHttpResponseDetails(response)
.addTag(LogUtils.TAG_CALLOUT);
if (ex != null) {
logBuilder.setExceptionDetails(ex).addTag(LogUtils.TAG_EXCEPTION);
}
Logger.saveLog();
}
@TrangOul that looks great! Your new code looks much cleaner, I'm glad that the newEntry()
method was helpful for this situation.
I'm going to close this issue & mark it as "wontfix" due to the downstream complications I mentioned with allowing the entry logging level to be changed - but please let me know if you need anything else!