Is there a proper way to create an authorization header that can regenerated every time you POST using the HTTP appender?
Background: The authorization header needs to be calculated every time we POST data to the api. This auth is the only method that is accepted via the API. It consists of a signature,ID,and the epoch time. It wont be able to be set as an environment variable because the api will not accept auth headers older than X minutes.
My current method is this: I am trying to use the Scripts in the configuration of the log4j2 to return a value that will be used in the HTTP appender
https://logging.apache.org/log4j/2.x/manual/configuration.html#Scripts
Here is my log4j2http.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="MyApp">
<Scripts>
<Script name="selector" language="groovy">
<![CDATA[
import org.apache.commons.codec.binary.Hex
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import java.security.MessageDigest
def id="XXXXXXXXXXXXXx"
Long epoch_time = System.currentTimeMillis()
Mac hmac = Mac.getInstance("HmacSHA256")
hmac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"))
def signature = Hex.encodeHexString(hmac.doFinal("GET${epoch_time}${path}".getBytes())).bytes.encodeBase64()
return "${id}:${signature}:${epoch_time}"
]]>
</Script>
</Scripts>
<Appenders>
<Http name="Http" url="https://XXX/rest/log/ingest" method="POST">
<KeyValuePair key="_Id:" value="{Id:"588"}" />
<Property name="Authorization" value="${result}" />
<Property name="Accept" value="application/json" />
<JsonLayout properties="true" />
</Http>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="Http" />
</Root>
</Loggers>
</Configuration>
App:
package App;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import java.io.*;
public class App {
public static void main(String[] args) {
System.setProperty("log4j2.Script.enableLanguages","groovy");
System.setProperty("log4j2.debug","false");
Logger logger = LogManager.getLogger("App");
LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File("log4j2http.xml");
context.setConfigLocation(file.toURI());
logger.debug("Debug log");
}
}
I'm not getting an error , just an empty ${result}. It is making me think that importing the groovy libraries is not working correctly or the script itself has errors. With debug on, it doesn't seem that I can see if the script is executing correctly. This likely doesn't seem to be the correct method nor do I know if this is possible.
2022-10-09 00:58:39,198 main DEBUG Installed 2 script engines
2022-10-09 00:58:39,251 main DEBUG Groovy Scripting Engine version: 2.0, language: Groovy, threading: MULTITHREADED, compile: true, names: [groovy, Groovy], factory class: org.codehaus.groovy.jsr223.GroovyScriptEngineFactory
2022-10-09 00:58:39,252 main DEBUG PluginManager 'Core' found 127 plugins
2022-10-09 00:58:39,252 main DEBUG PluginManager 'Level' found 0 plugins
2022-10-09 00:58:39,257 main DEBUG PluginManager 'Lookup' found 16 plugins
2022-10-09 00:58:39,259 main DEBUG Building Plugin[name=Script, class=org.apache.logging.log4j.core.script.Script].
2022-10-09 00:58:39,278 main DEBUG PluginManager 'TypeConverter' found 26 plugins
2022-10-09 00:58:39,292 main DEBUG createScript(name="selector", language="groovy", scriptText=".................")
2022-10-09 00:58:39,292 main DEBUG Building Plugin[name=scripts, class=org.apache.logging.log4j.core.config.ScriptsPlugin].
2022-10-09 00:58:39,295 main DEBUG createScripts(={selector})
2022-10-09 00:58:39,297 main DEBUG Script selector is compilable
2022-10-09 00:58:40,383 main DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
2022-10-09 00:58:40,388 main DEBUG KeyValuePair$Builder(key="_Id:", value="{Id:"588"}")
2022-10-09 00:58:40,389 main DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
2022-10-09 00:58:40,389 main DEBUG createProperty(name="Authorization", value="${result}", value="null")