I want to write Syslog using in java program on linux system. I don't want to use any library.
Assuming that "no libraries" means no 3rd-party libraries.
One approach would be to code your own implementation of the Syslog Protocol; see RFC 5424. You could do this in pure Java.
CORRECTION - Actually, not pure Java. The syslog protocol (typically) uses UNIX Domain sockets, and there is no built-in Java library functionality for this. You would need to resort to native code, or a 3rd-party library; see UNIX Domain Socket in Java
A second approach would be to write a JNI wrapper for the syslog(3) C library methods. Under the hood, this library opens a datagram socket on a local port and (presumably) implements the Syslog Protocol. So you don't achieve much by doing it this way.
(Note that the C libraries are part of (at least) any GNU/Linux system, so this doesn't count as using a 3rd-party library. At least, not in my books ...)
I used the system logger with a Runtime like this:
public static void log(String TextToLog){
Runtime r = Runtime.getRuntime();
try{
r.exec("logger \"Applicationname " + TextToLog + "\"");
}
catch(IOException e){e.printStackTrace();}
}
If the distribution uses systemd, you can use the following.
String logMessage = "some message";
String logIdentifier = "java-app";
String command = "echo " + logMessage + " | systemd-cat -t " + logIdentifier;
new ProcessBuilder(new String[] {"bash","-c","eval " + command}).start();
To watch in GNU/Linux's terminal, watch for your logIdentifier:
watch -n0.5 sudo journalctl -t "java-app"
Related
Is it possible to get the current RAM usage of a java Process that is created with Runtime.getRuntime().exec(...);. I am creating a minecraft server instance and I need to monitor the resource usage of the server.
Here is exactly how I am creating the process.
private void runStartCommand(){
try {
lines = new ArrayList<>();
String cmd = "cmd.exe /c cd " + service.getLocation() + "& java -jar -Xmx2G -Xms2G "+service.getLocation()+"spigot-1.9.2.jar";
process = Runtime.getRuntime().exec(cmd);
input = new BufferedReader(new InputStreamReader(process.getInputStream()),8*1024);
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
running = true;
} catch (IOException e) {
e.printStackTrace();
}
}
Bukkit already provides a custom plugin for monitoring and managing Minecraft server performance that should suit you perfectly.
Usually you would use something like Java Melody or a JMX console to monitor the application server process. You can also instrument and monitor it with the built-in VisualVM.
http://linux.die.net/man/1/dstat
if you are under linux, you can try dstat. We use it to take control over cpu, disk e ram usage
You could try to run systeminfo but you should really consider not doing it from Java but running some other tool (your could use nagios) on the OS - that way your monitoring isn't dependent on the app you're running.
Java does not have primitives for ICMPs and traceroute. How to overcome this? Basically I'm building code that should run in *nix and Windows, and need a piece of code that will run in both platforms.
Here's what I wrote today to "implement" the trace route command in Java. I've only tested in windows but it should work in Linux as well although there are several traceroute tools available for Linux so most likely there need to be some checks for the existence of those programs.
public class NetworkDiagnostics{
private final String os = System.getProperty("os.name").toLowerCase();
public String traceRoute(InetAddress address){
String route = "";
try {
Process traceRt;
if(os.contains("win")) traceRt = Runtime.getRuntime().exec("tracert " + address.getHostAddress());
else traceRt = Runtime.getRuntime().exec("traceroute " + address.getHostAddress());
// read the output from the command
route = convertStreamToString(traceRt.getInputStream());
// read any errors from the attempted command
String errors = convertStreamToString(traceRt.getErrorStream());
if(errors != "") LOGGER.error(errors);
}
catch (IOException e) {
LOGGER.error("error while performing trace route command", e);
}
return route;
}
You'll need the jpcap library (maybe the SourceForge jpcap is working too) and use the ICMPPacket class to implement the desired functionality.
Here is the Java traceroute implementation using the jpcap library .
I have a Java webstart process that is part of a windows batch script. I'm using the javaws command in a batch script in this case.
This match script ( start.bat) is invoked programatically using the "apache commons exec". Under some conditions the java process invoked by javaws hangs and I'd have to kill the entire process thread starting from the batch script start.bat.
Is there a programatic way of doing killing an entire process tree through apache commons exec?
I've tried using the "execWatchdog.destroyProcess();" on the "start.bat" script. However it only kills the start.bat process and not the entire process tree.
Is there a way of killing the entire process tree through apache-commons-exec or a similar code?
I've seen this question Performing equivalent of "Kill Process Tree" in c++ on windows that performs an equivalent task in c++. I'm wondering if anyone has implemented calling windows native system calls through JNI.
Finally got something workable even though its a roundabout way.
Apache Commons Exec API contains the CommandLauncher class that returns a java.lang.Process object. Thanks to the link
Here the link to get the windows Process Id from a java.lang.Process. This uses the JNA libraries.
Finally with the Process Id, here the command string that kills the process tree
//String killCmd = "taskkill /F /T /PID " + JNAHandler.getPid(process);
Unfortunately, as you've discovered, there isn't a pure Java way of doing this. You'll have to resort to native commands or JNI libraries, all of which are platform-dependent and more complex than a pure Java solution would be.
It may be worth upvoting the relevant bug in the Java bug database: http://bugs.sun.com/view_bug.do?bug_id=4770092
With luck we can persuade the Java developers that the poor handling of subprocesses is worth fixing for Java 8.
As far as I know, there's no such option in commons-exec. It's not even possible to obtain the PID of whatever process you just started. You could trap the kill signal within your bash script, and have the handler kill the subprocess(es) when the script process is killed.
Java Version 9 Onwards,
Java has come up with feature that can query and kill the main process and its descendants.
A code snippet to query about the child processes
import java.io.IOException;
public class ProcessTreeTest {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().exec("cmd");
System.out.println("Showing children processes:");
ProcessHandle processHandle = ProcessHandle.current();
processHandle.children().forEach(childProcess ->
System.out.println("PID: " + childProcess.pid() + " Command: " + childProcess.info().command().get()));
System.out.println("Showing descendant processes:");
processHandle.descendants().forEach(descendantProcess ->
System.out.println("PID: " + descendantProcess.pid() + " Command: " + descendantProcess.info().command().get()));
}
}
To kill the process and its children, Java9 has API
Iterate through all the children of the process and call destroy on each of them
For Example : As in your case you are getting Process object from apache-commons, then try out following code
Process child = ...;
kill (child.toHandle());
public void kill (ProcessHandle handle)
{
handle.descendants().forEach((child) -> kill(child));
handle.destroy();
}
References :
https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessHandle.html
https://www.tutorialspoint.com/how-to-traverse-a-process-tree-of-process-api-in-java-9
How do i terminate a process tree from Java?
Note - I have not tried this feature, Just reading about Java9 and
found helpful to share here.
Is it possible to get a list of installed applications (like the list from the un-install programs) from a windows vista computer with java?
If you mean installed applications I don't think it's possible by directly using Java SDK (also because it's not a cross platform requirement).. what I think you can do is to use an external native API to interact with windows registry (like jRegistryKey) and retrieve the information you need..
Instead if you want to get all the running applications from a Java program you could parse tasklist.exe output as explained here.
Not a Solution but a workaround!!
Getting windows native information using java SDK is not possible without support of external APIs. Instead of using external APIs (which is mostly LGPL licensed and not completely open), we can use the shell commands to get the same.
For getting the installed softwares list, use ProcessBuilder or Runtime.exec to run one of the following PowerShell commands:
Get-WmiObject -class Win32_Product | Select-Object -Property Name - This is bit slower! It uses Win32_Product class.
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate - This is faster and can give additional details. This uses PS registry provider.
You can stream the output of these and process it.
This is just a workaround and it is as per my analysis. As java is completely platform independent, fetching native information becomes difficult and the use of platform native tools (like command shell,, power shell etc.,) is a must.
package Vishal;
import com.sun.jna.platform.win32.Advapi32Util;
import static com.sun.jna.platform.win32.WinReg.HKEY_LOCAL_MACHINE;
import java.util.ArrayList;
import java.util.TreeMap;
public class GenerateInstalledApplicationList
{
ArrayList<String> getlist()
{
ArrayList<String> arr = new ArrayList();
String [] keys = Advapi32Util.registryGetKeys(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
String temp;
for (String key : keys)
{
temp = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall" + "\\" +key;
TreeMap<String, Object> tr = Advapi32Util.registryGetValues(HKEY_LOCAL_MACHINE,temp);
if(tr.isEmpty())
{
if(!key.contains("Update"))//all the instances of update are not actually installed applications
{
arr.add(key);
}
}
else
{
if(tr.containsKey("DisplayName"))
{
String str = (String) tr.get("DisplayName");
if(!str.contains("Update"))
{
arr.add(str);
}
}
}
}
return arr;
}}
Just Copy and paste this code it will return all the installed applications
only thing you will need is the jna api.
How can I write from Java to the Windows Event Log?
Log4J is a Java-based logging utility. The class NTEventLogAppender can be used to "append to the NT event log system". See the documentation here:
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/nt/NTEventLogAppender.html
Edit: There is a newer version, Log4j 2 "that provides significant improvements over its predecessor."
You can use JNA to write to the Event Log directly without the need of any native DLLs. See Advapi32 and Advapi32Util classes for various event log methods (ships since JNA 3.2.8).
If you're using Log4j, consider Log4jna instead of NTEventLogAppender.
You can also use the eventcreate command on Windows XP Pro and above.
String command = "eventcreate "
+ " /l APPLICATION"
+ " /so \"" + applicationObjectName + "\""
+ " /t " + lvl
+ " /id " + id
+ " /d \"" + description + "\"";
Runtime.getRuntime().exec(command);
For XP home and lower, you could create a vbs application that writes using the wscript.shell.eventcreate method. However you sacrifice the ability to specify source.
Example:
http://www.ozzu.com/mswindows-forum/posting-event-log-with-batch-files-t76791.html
Back in 2001 JavaWorld published an article on how to write messages to the Windows NT Event Log. Or, you can take a look at the Log4j NTEventLogAppender class.