log4j 2 - logger.entry(p1,p2,p3) with parameter names - java

Is there an easy way to use logger.entry(p1,p2,p3) from log4j 2 with the parameter names included in the output?
logger.entry(p1,p2,p3)
Result:
... entry params(val1, val2, val3)
But shut result in:
... entry params(p1=val1, p2=val2, p3=val3)
Edit:
The problem with a simple solution like
logger.info(p1+" "+p2+" "+p3);
or
logger.entry("p1="+p1,"p2="+p2,"p3="+p3)
is that the string is build before every function call and results in a performance lose. I ask me, if there is a build in way in log4j.

You can try something like this:
logger.entry("p1="+p1,"p2="+p2,"p3="+p3)

Related

YamlBeans: Turning an object into a hashmap

I have a Yaml file that's something like below:
rules:
- p_table:
["p_event/Name",
"p_fault/Name"]
- s_table:
["s_event/Name",
"s_fault/Name"]
- r_table:
["r_event/Name",
"r_fault/Name"]
So, I can already take the .yml file above and parse through it with YamlBeans and print it out with code like below:
System.out.println(map.get("rules"));
This gives this kind of result:
[{p_table=[p_event/Name, p_fault/Name]},
{s_table=[s_event/Name, s_fault/Name]},
{r_table=[r_event/Name, r_fault/Name]}]
What I would like to do is more on this sort of level, where I can store it in a HashMap and actually use the specifics within the map, with something like this:
HashMap<String, ArrayList<Strings>> Policies = (HashMap)(map.get("rules"));
But when I do that I either have an exception thrown or it just returns null, is there a solution for this should I not be using HashMaps... or can I just not translate objects in such a way? I plan on replacing the String with another type from a different library that uses Strings but wanted to start at the bottom and then go up from there.
The obvious solution would be to remove the sequence from the YAML file:
rules:
p_table:
["p_event/Name",
"p_fault/Name"]
s_table:
["s_event/Name",
"s_fault/Name"]
r_table:
["r_event/Name",
"r_fault/Name"]
If you can't change the YAML file, you need to transform the data after loading it.

Build DB connection string from environment variables

I'm using the Play Framework (Java) and am not able to figure out how to use environment variables in my configuration file for building the database connection string. While I'm able to use environment variables like this (for user name and password):
default.username = ${?FU_MAIN_DB_USERNAME}
default.password = ${?FU_MAIN_DB_PASSWORD}
I'm not able to make it work in the url string. Perhaps this is a simple case of string processing in Scala that I'm missing, but since I'm working in Java, I could use some help.
So far, I have tried the url string in the following formats and failed:
Tried to add a $ to variable name to perform interpolation:
default.url = "jdbc:postgresql://$${?FU_MAIN_DB_HOST}:$${?FU_MAIN_DB_PORT}/$${?FU_MAIN_DB_NAME}";
But this doesn't substitute. Rather, it picks the string as such.
default.url = "jdbc:postgresql://${?FU_MAIN_DB_HOST}:${?FU_MAIN_DB_PORT}/${?FU_MAIN_DB_NAME}";
This too inserts the '$' and all verbatim. Then I thought maybe something like PHP-style will work
default.url = "jdbc:postgresql://${${?FU_MAIN_DB_HOST}}:${${?FU_MAIN_DB_PORT}}/${${?FU_MAIN_DB_NAME}}";
But no.
I also tried doing stuff like "jdbc:postgresql://".concat(${?FU_MAIN_DB_HOST}) ... but this also inserts '.concat' verbatim.
Finally, I tried concatenation using the '+' operator, but I'm told (by my IDE) that symbols like +: etc. are not allowed in the application.conf file.
How then, in God's name, am I supposed to do that?!
The double quotes turn off interpolation. But you need to do that for the : and the //.
Try
default.url = "jdbc:postgresql://"${?FU_MAIN_DB_HOST}":"${?FU_MAIN_DB_PORT}/${?FU_MAIN_DB_NAME}
Maybe you are better off to set the whole thing in one big environment variable instead.

Apache Commons Configuration get property based on parent with attribute equal to value

I'm using Apache Commons Configuration with XML for the configuration of my application, and I'm having trouble getting a property that I want.
I have the following XML structure (minimal structure just to get point across):
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<planets>
<planet name="mars">
<terrain>terrain/mars.terrain</terrain>
</planet>
<planet name="earth">
<terrain>terrain/earth.terrain</terrain>
</planet>
</planets>
</settings>
As I understand it, the best I can do here to get the mars terrain setting is:
config.getProperty("planets.planet(0).terrain");
Unfortunately, my app doesn't/shouldn't have any concept of the indexes of these planets. At least, the indexes aren't going to be consistent. They could change at any time, so it's unreliable to refer to them by index as is done above.
So, what I want to be able to do is something like this:
config.getProperty("planets.planet[#name=mars].terrain");
That doesn't work, as you might have guessed. The only other way I've found to do it is obtuse and unacceptable:
List<Object> planets = config.getList("planets.planet[#name]");
String terrain = "";
for (int i = 0; i < planets.size(); i++) {
if (planets[i].toString().equals("mars")) {
terrain = config.getString("planets.planet(" + i + ").terrain");
break;
}
}
I'm sure you can see why that's undesirable. Now, I'm to the point where I'm considering just wrapping/extending the Apache Commons Configuration library in order to add this type of functionality, but I'm just unwilling to accept that there isn't an easier way to do this.
Question Revisited
What am I overlooking, and how can this be accomplished in a simpler manner? Does this functionality simply not exist?
I found out that I could replace the DefaultExpressionEngine with an XPathExpressionEngine.
XMLConfiguration.setDefaultExpressionEngine(new XPathExpressionEngine());
This allowed me to use XPath to get my properties, and I could now do:
String terrainFile = config.getString("planets/planet[#name='mars']/terrain");
One thing to note is that you need the Apache Commons JXPath lib to use the XPathExpressionEngine, or you will get an error when you try to create it.

Java LinkedHashMap not maintaing the order of insert when looped in Play Framework 2.0 template

In play framework's (2.0) application controller I am creating a java
LinkedHashMap<String, List<MyObject>) to maintain the order in which I am inserting the string key.
I tried iterating this LinkedHashMap in template like below:-
#for(currentKey <- linkedHashMapInstance.keySet()){
....
loop myObjectList for the currentKey
....
}
I got random order whenever I refresh the screen.
Then I tried to change the logic of looping by
#for((currentKey , currentList) <- mapOfCards){
.. used the key and the list
}
Now I am getting a consistent order but not the order which I inserted..
The debug log in the server side is showing the correct order.
I was under assumption that LinkedHashMap in Java will maintain the order of inserts
even when it is rendered in a scala template.
Am I doing something wrong here?
I've faced the same issue a few months ago. As #nico_ekito pointed out, it's a problem related to the Java->Scala conversion.
To fix it, try something like this:
#for((currentKey , currentList) <- SortedMap.empty[String, String] ++ mapOfCards) {
}
by replacing [String, String] by the types of your (currentKey , currentList).
Hope that helps, it worked for me.
It may be related to the Java->Scala conversion.
Try using .asScala like this:
#for((currentKey , currentList) <- mapOfCards.asScala){
..
}
Update :
It works with:
#for((currentKey , currentList) <- scala.collection.mutable.LinkedHashMap.empty[String, String] ++ mapOfCards) {
}

Drools collect pattern problem

I have a rule LHS like that
when
$location : Location()
$cabinets : ArrayList() from collect ( Cabinet() from $location.elements() )
then
an when I print the content of #cabinets in RHS I see that it contains all elements (also those that are not of class Cabinet ).
I want to collect ontly cabinets from $location>elements().
What did I do wrong ?
I think you would say something along the lines of
Cabinet(class == Cabinet.class)
I dont think that Drools is doing an explicit type check on the Cabinet classes as you have them afaik.
Your question is about the 'from' pattern, not the 'collect' one.
Following rule should help to test:
when
$location : Location()
$cabinet : Cabinet() from $location.elements()
then
This rule should fire for each Cabinet in location.
You can try to post your question on the rule-users user list

Categories

Resources