blob: 88264618436781bda6d6fd12f858d9929efe0b10 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.cta.impl;
import static java.util.Objects.requireNonNull;
import java.util.Formatter;
/**
* Simple logger abstraction
*
* <p>This is an intentionally simple and simplistic logger for agent-internal usage. Since the agent environment
* is limited and can make no assumption about how it will be used, it only uses the console and no
* external libraries.</p>
*
* <p>It is required to call {@link #configure(String)} before accessing the log instance using {@link #get()}.</p>
*
*/
abstract class Log {
private static Log INSTANCE; // NOSONAR - name is OK for static fields
/**
* Configures the global logger instance
*
* @param spec the logger spec, <tt>v</tt> for a console log, anything else for a no-op log
*/
public static void configure(String spec) {
boolean isVerbose = "v".equals(spec);
boolean isExtraVerbose = "vv".equals(spec);
INSTANCE = isVerbose || isExtraVerbose ? new ConsoleLog(isExtraVerbose) : new NoopLog();
}
/**
* Gets the global logger instance, configured with {@link #configure(String)}
*
* @return the global logger instance
* @throws NullPointerException in case the logger is not configured
*/
public static Log get() {
return requireNonNull(INSTANCE, "Log is null, did you foget to call Log.configure() ?");
}
private Log() {
}
/**
* Logs a message
*
* <p>The message and the arguments are interpolated using a {@link Formatter}, e.g.
*
* <pre>Logger.get().log("Transforming %s", klazz.getName());</pre>
*
* </p>
*
* <p>The line separator <tt>%n</tt> is automatically appended to the message.</p>
*
* @param msg the message
* @param args the arguments
*/
public abstract void log(String msg, Object... args);
public abstract void trace(String msg, Object... args);
/**
* Prints the throwable stack trace and throws a <tt>RuntimeException</tt>
*
* @param message the message to include in the <tt>RuntimeException</tt>
* @param t the throwable to print the stack trace for
*/
public abstract void fatal(String message, Throwable t);
static class ConsoleLog extends Log {
private static final String LOG_ENTRY_PREFIX = "[AGENT] ";
private final boolean trace;
ConsoleLog(boolean trace) {
this.trace = trace;
}
@Override
public void log(String msg, Object... args) {
System.out.format(LOG_ENTRY_PREFIX + msg + " %n", args); // NOSONAR - this is a logger, OK to use System.out
}
@Override
public void trace(String msg, Object... args) {
if ( !trace )
return;
log(msg, args);
}
@Override
public void fatal(String msg, Throwable t) {
// ensure _something_ is printed, throwable might not be printed
t.printStackTrace(); // NOSONAR - OK to use printStackTrace, we are a logger
throw new RuntimeException(LOG_ENTRY_PREFIX + msg, t); // NOSONAR - we don't want custom exceptions
}
}
static class NoopLog extends Log {
@Override
public void log(String msg, Object... args) {
// empty by design
}
@Override
public void fatal(String message, Throwable t) {
// empty by design
}
@Override
public void trace(String msg, Object... args) {
// empty by design
}
}
}