How to use map lookups using Log4j2? - java

I have been looking over these three sites on how to create a map lookup (or any other lookup for that matter) using log4j2:
http://logging.apache.org/log4j/2.x/manual/extending.html#Lookups
http://logging.apache.org/log4j/2.x/manual/lookups.html
http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution
I understand the general idea behind what I am reading, I am just having a difficult time putting all the bits and pieces together.
Goal
To be able to place a variable, of some sort, in a log4j2.xml file that at configuration time, or runtime, replaces that variable with the values in a resource bundle. This is what i have so far:
Configuration File
Lookup Class
The getValue(key) method looks in a resource bundle for the email values associated with that key.The #Plugin name is "map" which, if i have read correctly, is related to prefixes in the .xml file that are also "map". So, wouldn't "error.notification.emails" get passed into the lookup(String key) method in the MapPropertiesLookup class? What do i need to do in order to get this to work?

Yes, map is the name of the lookup you are creating. Since Log4j already has a Lookup named map creating another is going to cause problems.
Yes, error.notification.emails should be passed as the key value to the Lookup. Assuming that getValue(key) works your lookup would probably work if it was named something else.
However, it might make more sense for you to file a Jira and ask for a ResourceBundleLookup where the syntax could be something like: ${bundle:bundleName:key}. Of course, "bundleName:key" would be passed to the lookup as the key and it would split the key into the component parts.
If you have further problems you might consider asking on the Log4j developers mailing list.

I added a new lookup for the next release (whether it is a beta or release candidate):
Committed revision 1531064.
You can use it now if you build Log4J from source. The format is documented if you build the site, it is used as follows:
${bundle:BundleName:BundleKey}
For example:
${bundle:com.domain.Messages:MyKey}
The java.util.ResourceBundle class will look for com/domain/Messages.properties on the classpath.
Our JIRA issue: https://issues.apache.org/jira/browse/LOG4J2-420

Related

Is using one class to store data safe?

So I was searching about storing data in one class, and found this. However, that's not what I'm looking for. What I wanted to know about this was whether it's bad practice, can cause performance issues in an application, or if there's another way to do it, etc... (and I'm not doing this on an Android).
Let's say I have a class that stores a HashMap<Enum, Object> and is initialized when I create the class in main.
public Main() {
// Creates the HashMap, initialized in the constructor 'MemoryContainer'
MemoryContainer m = new MemoryContainer();
m.getTestHash().put(SomeEnum.TEST, "Test"); // Using created HashMap
}
Other than casting the value every time I use it, would this cause major issues? If so, is there an alternative?
There's nothing wrong with storing static values in a class, however this is not a good practice.
To store the constants you should create an interface as every field in an interface is already a constant (public static final).
A better approach will be to store these values in properties files, and load them as needed.
A properties file can be stored externally and a person who isn't aware of your source code would be able to modify this properties file if needed. For example you can store database connection details in properties files and if server support admin determines that database instance is down, he/she can edit the properties file to point the application to a new one.
Finally for most flexibility you shouldn't store the configuration inside application at all. It can be stored in a database like MySql or in a fast data structure storage like Redis. This will allow multiple instances of your application to share the configuration data and it will also allow you to modify configuration on the fly by modifying them in the database.
Sometimes a Git repository is also used to store this kind of data (like in case of microservices). Git repository in addition to being shared among all the instances, also maintains the history of modifications.
I would not look too much at performance issues (of course, I do not know what else your application does or wants to do and how it achieves it).
What you should look at first is Mutability - in your example, nothing would stop me from changing the configuration at Runtime by calling
m.getTestHash().put(SomeEnum.TEST, "NotATestAnymore") - this would immediately change the behaviour for every other use of that specific setting.
I am also not sure why you would not just use a configuration class that would directly provide (typed) getters and, if you know all configuration settings at the launch of the app, one constructor containing all the settings.
Do you plan to read the configuration from an outside source (e.g. file)?
NO,
It won't cause major issues.
Also, it is a good practice to keep those variables (HashMap in your case) in a different class away from your main class (which contains your app logic).

Freemarker Customize TemplateCache storage want to read the information from TemplateKey

I have my own customized freemarker template storage configured over freemarker, it is working fine.
Recently I want to make some changes on the cache management, I need to read the properties from the cache key which is typeof "TemplateKey". Unfortunately the "TemplateKey" is "private final static class". I have no access to this class and I cannot cast the Key object back into TemplateKey object.
I see the simplest way is to make source code change in TemplateCache.java to update the TemplateKey to be expose as public class.
Question to Freemarker designer: Is it any special reason to make this TemplateKey not be exposed? Is it possible to expose it in next build?
Thanks.
Rocky
At the first glance, I would keep the key class private, because exposing it would introduce a backward-compatibility constraint that can be in the way of further development. But what exactly is your use case that require information from the key?
We disabled localelookup, in this case, one FTL file are working for all locales. But the key includes locale, so sampe template was cached per locale, it is duplicated in memory.
One solution is: remove locale in key when manage it in cache, so I need read key properties. But it still need combine with other changes such as make template clone-able.
Please refer to this POS for detail: Freemarker Template Cache are in same content when locale are different, is it a concern on wasting memory?
Thanks.

Looking for an OSGi Design-Pattern

I'm currently facing an interesting problem in my OSGi application.
I'm implementing a configuration service that should retrieve the application's configuration from multiple sources (file, registry or network). The configuration service should read from the sources in a special order until he got a value for the configuration property.
First I thought of putting each source in a separate bundle, create a super interface for them and let them provide a declarative service. This would also help to modularize the registry which is required since it is not available on every OS. When the configuration service is asked for a property's value it queries for all source bundles according to the whiteboard pattern and reads the configuration until he got a non-null value. But it does it in a random order.
Does anyone have an idea how to implement a special order in traversing the bundles providing the configuration service?
Best regards
OSGi already has a concept of service ranking. When registering a service, you can provide a value for the property "service.ranking" (org.osgi.framework.Constants.SERVICE_RANKING).
I don't think that this property has any effect on the order in which BundleContext#getServiceReferences() returns available service references (at least the spec doesn't say anything about it) , but you could still use the property value to order the internal collection managed by your "super" config service.
However, to me it is generally a strange idea to let the service implementation itself determine its relative importance. I would rather split the problem in two parts.
A config service acting as a facacde for
a collection of config source providers
The second interface would include some characterization concept (e.g. an enum {file, registry, net}). I would then have the implementation of the first interface (the facade) perform the ordering based on the characteristic of each provider (as the first answer by Chris already suggests).
In general if you need a special order of traversing for a bunch of objects, you just define a (partial) order between your objects.
Then, you sort the objects you've got and go through that list.
So, for your problem, when a property's value is needed, you find all the sources, you sort them in a list and finally iterate though it.

How to persist configuration settings in Spring?

I have a set of configuration settings (key/value) pair, which is meant for customization (through an admin panel for example) through Spring MVC. Are there any wide-accepted way of accomplishing this?
One has suggested using a one-row table to persist, but other has dismissed this as a bad design. What are my options? I am thinking that a property file should be sufficient in this case, but it is not exactly clear to me how to map this property file to a java object, as a model, save and update it ...
Thanks for your help
Oliver
Where I work we often simply have a configuration table with two columns, one for key, one for value. This seems to work well. This is context-less, but can be put into context simply by adding another column for 'customer_id' for example, or 'site_id'.
class ConfigurationValue {
String key, String value;
// blah, blah
}
Then just use the JDBC template to do reads/inserts/etc...
No magic here.
java.util.Properties gives you a simply interface to read/write .properties files in Java. That might be suitable for your case, but depends largely on your application.

Loading Settings - Best Practices

I'm at the point in my first real application where I am adding in the user settings. I'm using Java and being very OO (and trying to keep it that way) so here are my ideas:
Load everything in the main() and
pass it all 'down the line' to the
required objects (array)
Same as above, but just pass the
object that contains the data down
the line
Load each individual setting as
needed within the various classes.
I understand some of the basic pros and cons to each method (i.e. time vs. size) but I'm looking for some outside input as to what practices they've successfully used in the past.
Someone should stand up for the purported Java standard, the Preferences API... and it's most recent incarnation in JDK6. Edited to add, since the author seems to savvy XML, this is more appropriate than before. Thought I believe you can work XML juju with Properties too, should the spirit take you.
Related on SO: Preferences API vs. Apache solution, Is a master preferences class a good idea?
(well, that's about all the standing up I'm willing to do.)
Use a SettingsManager class or something similar that is used to abstract getting all settings data. At each point in the code where you need a setting you query the SettingsManager class - something like:
int timeout = SettingsManager.GetSetting("TimeoutSetting");
You then delegate all of the logic for how settings are fetched to this single manager class, whose implementation you can change / optimize as needed. For instance, you could implement the SettingsManager to fetch settings from a config file, or a database, or some other data store, periodically refresh the settings, handle caching of settings that are expensive to retrieve, etc. The code using the settings remains blissfully unaware of all of these implementaton decisions.
For maximum flexibility you can use an interface instead of an actual class, and have different setting managers implement the interface: you can swap them in and out as needed at some central point without having to change the underlying code at all.
In .NET there is a fairly rich set of existing configuration classes (in the System.Configuration) namespace that provide this sort of thing, and it works out quite well.
I'm not sure of the Java equivalent, but it's a good pattern.
Since configuration / settings are typically loaded once (at startup; or maybe a few times during the program's runtime. In any way, we're not talking about a very frequent / time-consuming process), I would prefer simplicity over efficiency.
That rules out option number (3). Configuration-loading will be scattered all over the place.
I'm not entirely sure what the difference is between (1) and (2) in your list. Does (1) mean "passing discreet parameters" and (2) mean "passing an object containing the entire configuration"? If so, I'd prefer (2) over (1).
The rule of thumb here is that you should keep things simple and concentrated. The advantage of reading configuration in one place is that it gives you better control in case the source of the configuration changes at some point.
Here is a tutorial on the Properties class. From the Javadocs (Properties):
The Properties class represents a
persistent set of properties. The
Properties can be saved to a stream or
loaded from a stream. Each key and its
corresponding value in the property
list is a string.
A property list can contain another
property list as its "defaults"; this
second property list is searched if
the property key is not found in the
original property list.
The tutorial gives the following example instantiation for a typical usage:
. . .
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
// create application properties with default
Properties applicationProps = new Properties(defaultProps);
// now load properties from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
. . .
You could, of course, also roll your own system fairly directly using a file-based store and an XML or YAML parser. Good luck!
We have recently started using JSR-330 dependency injection (using Guice from SVN) and found that it was possible to read in a Properties file (or any other map) and bind it inside Guice in the module in the startup code so that the
#Inject #Named("key") String value
string was injected with the value corresponding to the key when that particular code was called. This is the most elegant way I have ever seen for solving this problem!
You do not have to haul configuration objects around your code or sprinkle all kinds of magic method calls in each and every corner of the code to get the values - you just mention to Guice you need it, and it is there.
Note: I've had a look at Guice, Weld (Seam-based) and Spring which all provide injection, because we want JSR-330 in our own code, and I like Guice the best currently. I think the reason is because Guice is the clearest in its bindings as opposed to the under-the-hood magic happening with Weld.

Categories

Resources