How to log Process id using Log4cxx or log4j - log4j

I am using log4cxx my project and i can able to log current thread id using [%t] marker, how to log process id in it or log4j?.
I am using ConversionPattern & xml based configuration file.
Thanks,

Based on the above answers, I'm going to do this in log4j as follows:
import java.lang.management.*;
import org.apache.log4j.MDC;
private String getPID() {
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
return rt.getName();
}
private void configLog4j() {
// call this from somewhere before you start logging
MDC.put("PID", getPID());
}
Then in my log4j.properties:
log4j.appender.FILE.layout.ConversionPattern=%d %X{PID} [%t] %p %c{1} %x - %m%n
This will actually yield a PID that consists of the ID number and the hostname, at least on my implementation of Java, and from what I read that could be implementation specific. You could go further and split out just the PID.

I've grepped through log4j's and log4cxx's documentation and nowhere did I find anything about logging process id.
So, to be short: no, you can't log process id, at least not directly.
Since you're using C++, you can get your program's PID. Here is how to do it in Linux (Ubuntu in this link). Here is how do do it in Windows.
Get that PID at your program start, use an MDC and put your PID in it.
I don't think there's a better way.
Doing this in log4j would be even trickier, since I know of no way for a running program to get it's PID using standard Java classes.

This doesnt exist in any of the log4xxx, but with a litle effort you can make it yourself. Actually it's a very simple task if you don't mind a little coding. This is basically what I did few times - override actual appender, or it's layout, make sure your class sticks the process ID into event properties map. Then use this property by name as if it was an MDC property. Using MDC directly like suggested above is not the best choice because they are thread bound and you will have to make sure every thread puts the PID when it starts. But if you can't or don't want to override the appender or layout, then this would probably be the only option.

The answer by #skiphoppy works very well for Log4j1.x, but I thought it could be updated to show how it works in the new Log4j2.
(NOTE: I tried to submit this as an edit of the posting above as it is only a minor revision of the answer code, but I'm posting it as a separate answer since my revision was rejected.)
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import org.apache.logging.log4j.ThreadContext;
private String getPID() {
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
return rt.getName();
}
private void configLog4j() {
// Here is the Log4j2 way
ThreadContext.put("PID", rtmx.getName());
}
As skiphoppy's answer states, it outputs a little more than just the process ID. For instance, on my machine (Fedora 20):
16237#localhost.localdomain
You can extract just the process id with the following code, placed in your XML configuration file: %replace{%X{PID}}{[A-Za-z#\.]*}{}
Given the output above for the process id:
16237#localhost.localdomain
the regex will produce
16237

There is no feature in Log4J to achieve this, however you could pass the process id in and use that.
This blog post shows one way to go about it: http://blackbeanbag.net/wp/2009/01/14/log-file-management-in-coherence-using-log4j/
Basically, pass in the process id as a system property and then use that in the Log4j pattern.
Apparently, this is due to the JVM not providing an easy method to access the process id. From JDK1.5+, this may work.
(Archived from dead link http://www.theresearchkitchen.com/archives/100 )

Related

MapUtils with Logger

I am using MapUtils.verbosePrint(System.out, "", map) to dump the contents of a map in Java. They (management) do not like us using System.out.println().
We are using log4j. They made the logger into a variable "l" so we can say something like l.debug("This is going to the logfile in debug mode).
I would like to get the output buffer(s) from l so I could pass it into verbosePrint() instead of System.out. I looked at all the methods and members of the logger and did things like getAppenders() and tried all those elements but I could not find anything that helped.
Has anyone else done this? I know the logger may write to > 1 output.
You can use Log4j IOStreams to create PrintStreams that will send everything to a logger. This is mostly useful to log debug output from legacy APIs like JDBC or Java Mail that do not have a proper logging system. I wouldn't advise it in other cases, since your messages might be merged or split into several log messages.
I would rather use one of these approaches:
simply log the map using Logger#debug(Object). This will lazily create an ObjectMessage (only if debug is enabled), which is usually formatted using the map's toString() method. Some layouts might format it differently (like the JSON Template Layout).
eagerly create a MapMessage or StringMapMessage:
if (l.isDebugEnabled()) {
l.debug(new MapMessage(map));
}
This gives you more formatting options. For example the layout pattern %m{JSON} will format your message as JSON.
if your are set on the format provided by MapUtils#verbosePrint, you can extend ObjectMessage and overwrite its getFormattedMessage() and formatTo() methods.
public String getFormattedMessage() {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
MapUtils.verbosePrint(new PrintStream(os), "", );
return new String(os.toByteArray());
}

switching FileAppenders on the fly

I've got a legacy logging class. Its got a static Logger reference (named logger) and a bunch of static methods.
Each method takes a String input and writes it to System.out.println and to logger if logger is not null.
Its got a constructor that initializes logger. But this constructor only has package scope and I'm pretty sure its not being called anywhere. Therefore logger is always null and the class essentially only ever executes System.out.println
I want to change this so it can be used in a multi threaded application where each thread writes to its own unique FileAppender.
And that's where I'm stuck.
Basically, what I want to do is have this static class associated with a bunch of different log4j FileAppenders. Each FileAppender can be created by the Thread, and the file name can be derived from unique information known to the Thread.
What I can't figure out how to do is magically use Log4j to communicate that Thread's unique FileAppender to this legacy logging class.
Ideas? Hints? Suggestions?
Mark
It is possible to change the target log file name dynamically using a RoutingAppender and the ThreadContext map.
This can all be done with configuration (no need for custom code where threads create FileAppenders). In the RoutingAppender configuration you can specify a ThreadContext key you want to use to switch the target FileAppender. For example, you can use the string "ROUTINGKEY". Each thread puts a unique value in the ThreadContext map for key "ROUTINGKEY", and this value is used to select the Appender that the log event is routed to. You can even set it up to dynamically create log files that have the ROUTINGKEY value in the file name, so not all target log files need to be known in advance.
The FAQ page has a good example: http://logging.apache.org/log4j/2.x/faq.html#separate_log_files

Log4j, dynamic file name based on .getLogger("") parameter

My application controls an arbitrary number of devices. I want to have log files for each of the devices. Basically, i want to be able to call LogManager.getLogger(deviceId) and log the corresponding thing.
I looked through a number of topics here and on other sites, still i am not quite sure if it is possible or not. I am not quite sure whether i should extend an appender or a logger.
How does one go about solving this task?
One solution, though it's not optimal, would be to add a fileappender in the constructor of your device object :
String device = "thing"
Logger log1 = Logger.getLogger("org.path."+device);
log1.setAdditivity(false);
log1.addAppender(new FileAppender(new SimpleLayout(), "org.path."+device ));

How do you forbid users from doing evil things in Groovy Scripts?

I'm planning to integrate Groovy Script Engine to my game so it will give the game nice moddability but how do you prevent players from writing evil scripts like deleting all files on C: drive?
Groovy includes library like java.io.File by default so it will be pretty easy to do once they decided to write such scripts.
I guess I can't prevent users from writing something like while(1==1){} but is there anyway to at least not let them allow to delete/modify files or something dangerous for PCs?
There's a blog post by Cedric Champeau on customising the Groovy Compilation process, the second part of it shows how to use SecureASTCustomizer and CompilerConfiguration to limit what Scripts can do (and then has examples of defining your own AST checks for System.exit, etc...
Look into the SecurityContext class.
The Groovy Web Console appears to have already solved this problem, because it won't execute something like System.exit(1). The source code is available on GitHub, so you can see how they did it.
If you're not sure where to start, I suggest getting in touch with the author, who should be able to point you in the right direction.
I know this is a old question. I'm posting this as it might help some people out there.
We needed to allow end-users to upload Groovy scripts and execute them as part of a web application (that does a lot of other things). Our concern was that within these Groovy scripts, some users might attempt to read files from the file system, read System properties, call System.exit(), etc.
I looked into http://mrhaki.blogspot.com/2014/04/groovy-goodness-restricting-script.html but that will not prevent an expert Groovy developer from bypassing the checks as pointed out by others in other posts.
I then tried to get http://www.sdidit.nl/2012/12/groovy-dsl-executing-scripts-in-sandbox.html working but setting the Security Manager and Policy implementation at runtime did not work for me. I kept running into issues during app server startup and web page access. It seemed like by the time the Policy implementation took hold, it was too late and "CodeSources" (in Java-Security-speak) already took its access settings from the default Java policy file.
I then stumbled across the excellent white paper by Ted Neward (http://www.tedneward.com/files/Papers/JavaPolicy/JavaPolicy.pdf) that explained quite convincingly that the best approach (for my use case) was to set the Policy implementation on JVM startup (instead of dynamically later on).
Below is the approach that worked for me (that combines Rene's and Ted's approaches). BTW: We're using Groovy 2.3.10.
In the [JDK_HOME]/jre/lib/security/java.security file, set the "policy.provider" value to "com.yourcompany.security.MySecurityPolicy".
Create the MySecurityPolicy class:
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.util.HashSet;
import java.util.Set;
public class MySecurityPolicy extends Policy {
private final Set<URL> locations;
public MySecurityPolicy() {
try {
locations = new HashSet<URL>();
locations.add(new URL("file", "", "/groovy/shell"));
locations.add(new URL("file", "", "/groovy/script"));
} catch (MalformedURLException e) {
throw new IllegalStateException(e);
}
}
#Override
public PermissionCollection getPermissions(CodeSource codeSource) {
// Do not store these in static or instance variables. It won't work. Also... they're cached by security infrastructure ... so this is okay.
PermissionCollection perms = new Permissions();
if (!locations.contains(codeSource.getLocation())) {
perms.add(new AllPermission());
}
return perms;
}
}
Jar up MySecurityPolicy and drop the jar in [JDK_HOME]/jre/lib/ext directory.
Add "-Djava.security.manager" to the JVM startup options. You do not need to provide a custom security manager. The default one works fine.
The "-Djava.security.manager" option enables Java Security Manager for the whole application. The application and all its dependencies will have "AllPermission" and will thereby be allowed to do anything.
Groovy scripts run under the "/groovy/shell" and "/groovy/script" "CodeSources". They're not necessarily physical directories on the file system. The code above does not give Groovy scripts any permissions.
Users could still do the following:
Thread.currentThread().interrupt();
while (true) {} (infinite loop)
You could prepend the following (dynamically at runtime) to the beginning of every script before passing it onto the Groovy shell for execution:
#ThreadInterrupt
import groovy.transform.ThreadInterrupt
#TimedInterrupt(5)
import groovy.transform.TimedInterrupt
These are expalined at http://www.jroller.com/melix/entry/upcoming_groovy_goodness_automatic_thread
The first one handles "Thread.currentThread().interrupt()" a little more gracefully (but it doesn't prevent the user from interupting the thread). Perhaps, you could use AST to prevent interupts to some extent. In our case, it's not a big issue as each Groovy script execution runs in its own thread and if bad actors wish to kill their own thread, they could knock themselves out.
The second one prevents the infinite loop in that all scripts time out after 5 seconds. You can adjust the time.
Note that I noticed a performance degradation in the Groovy script execution time but did not notice a significant degradation in the rest of the web application.
Hope that helps.

documentation on how to use MSBuild Namespace in C# Source code

I am looking for some simple answers on how to use funktionality from MSBuild in a c# program. The native documentation seems to be completely useless, because I only find information like:
ConsoleLogger.ApplyParameter
Applies a parameter to the logger
This is the prototype of a explanation, that had better never been written. Neither here, nor under the parameters type explanation you find e.g. a link or any examples about what the parameters might be there for, or their names, or where to find that information
The tutorials I find are all about MSBuild as a standalone tool.
At the moment I need to understand, how to get more information about a failed build:
This method just returns true or false.
bool success = project.Build(new string[] { "Build", "Deploy"}, fileLogger);
Also I need understand how to configure the filelogger, and how to use it from project.
Microsoft.Build.Logging.FileLogger fileLogger = new Microsoft.Build.Logging.FileLogger();
For the particular example in your question, ApplyParameter works the same way that the console logger parameters (/clp) work from the command line.
> msbuild /?
...
/consoleloggerparameters:<parameters>
Parameters to console logger. (Short form: /clp)
The available parameters are:
PerformanceSummary--Show time spent in tasks, targets
and projects.
Summary--Show error and warning summary at the end.
NoSummary--Don't show error and warning summary at the
end.
ErrorsOnly--Show only errors.
WarningsOnly--Show only warnings.
NoItemAndPropertyList--Don't show list of items and
properties at the start of each project build.
ShowCommandLine--Show TaskCommandLineEvent messages
ShowTimestamp--Display the Timestamp as a prefix to any
message.
ShowEventId--Show eventId for started events, finished
events, and messages
ForceNoAlign--Does not align the text to the size of
the console buffer
DisableConsoleColor--Use the default console colors
for all logging messages.
DisableMPLogging-- Disable the multiprocessor
logging style of output when running in
non-multiprocessor mode.
EnableMPLogging--Enable the multiprocessor logging
style even when running in non-multiprocessor
mode. This logging style is on by default.
Verbosity--overrides the /verbosity setting for this
logger.
Example:
/consoleloggerparameters:PerformanceSummary;NoSummary;
Verbosity=minimal
So for the example shown in the help,
logger.ApplyParameter("PerformanceSummary", "NoSummary");
logger.ApplyParameter("Verbosity", "minimal");
If you need a high degree of control over a logger you are attaching to the build engine from code, you might want to consider writing your own logger rather than trying to interpret/parse the text output from the stock console logger.

Resources