2

I need to configure Log4j 2.x logging with encryption key (AES). I have this part in the log4j2.xml:

<Encryption keyId="${sd:encryptionKeyId}" key="${sd:encryptionKey}">
    ....
</Encryption>

For testing purposes, I used an online generation tool to generate an AES key and I put it directly there instead of ${sd:encryptionKey}. It worked, ie. I didn't get any exceptions.

Then I wanted to move the key up to the properties, like so:

<Property name="sd:encryptionKey">---my key here---</Property>

It didn't work. I removed the sd: prefix and it worked again.

My question is: What does this prefix stand for and is setting the key directly in this file as a property the right way to do it?

developer10
  • 1,450
  • 2
  • 15
  • 31

1 Answers1

1

The ${sd:... prefix is for Log4j2’s built in Structured Data lookup.

From the manual:

The StructuredDataLookup is very similar to the MapLookup in that it will retrieve values from StructuredDataMessages.

Log4j2 offers other lookups so you could get items from system properties, environment variables, the Log4j2 thread context map etc.

It’s also easy to build a custom lookup that gets data from your application.

Important: a lookup needs the dollar and curly braces to work.

For the purpose of what you’re trying to achieve I would define a simple property like you’re doing in your question but perhaps put the key in an environment variable to prevent other people from discovering the key by reading the log configuration.

Defining environment variables is OS-specific but in Linux you could do it in your ~/profile, in Windows you’d go to Control Panel > System > Advanced > Environment variables.

Then use the environment variable lookup to allow Log4j2 to get the value.

<Property name="encryptionKey">${env:MY_AES_KEY}</Property>
Remko Popma
  • 35,130
  • 11
  • 92
  • 114
  • Thanks. But how come my example doesn't work with the prefix? I suspect then that I should be keeping the value somewhere else? Can you please suggest a location that is supposed to work with the prefix? – developer10 Dec 05 '17 at 07:39
  • Were you actually logging a StructuredDataMessage object? – Remko Popma Dec 05 '17 at 09:14
  • The `${sd:key}` lookup will only be able to render a value for log events with a `StructuredDataMessage`. This is not the default message. If you simply do `logger.log(“Hello {}”, “world”)` you’ll get a `ParameterizedMessage`. The sd lookup won’t work with that. You need to explicitly create a `StructuredDataMessage` object and log that. – Remko Popma Dec 05 '17 at 22:47
  • I accepted your answer the other day. However, I would like to ask you this: How and where do I write (I assume Java code) that I can then pass to my config log4j2.xml file, which will in turn to be able to use the key inside itself (${sd:key}? Ideally the log call will stay unchanged (eg. LOGGER.info("log message", param2, etc); However, these call methods do accept "Object..." argument so I guess if something is created for the key it could be put at the end of the method call? – developer10 Dec 07 '17 at 10:06
  • If your application logs like `logger.info(“hi {}”, parameter)` then you shouldn’t use the `${sd:key}` lookup because you aren’t logging StructuredDataMessage objects, you are logging ParameterizedMessage objects. – Remko Popma Dec 07 '17 at 11:38
  • This logging library is basically a wrapper around Log4J 2. The docs say that encryptionKey should be used like that: ${sd:encryptionKey} The method calls wont contain {}, so I dont think what you are saying is valid for this case (not to use StructuredDataMessage). I tried: StructuredDataMessage sdm = new StructuredDataMessage(id, msg, type); sdm.put("encryptionKey", "the key"); and then send it along the log message, like so: LOGGER.info("not parameterized log msg", sdm); However, this doesnt get picked up in .xml via ${sd:encryptionKey} – developer10 Dec 07 '17 at 12:49