A Java-based syslog server, everyone to see ah!

Keywords: Session Java network Maven

A Java-based syslog server

Preface

When I received a request to develop syslog, my expression was like this....
What is syslog? Haven't I heard of it? What's the use of this thing? Muddled three links...

Then ask my boss, he said syslog is what Barabala said a lot, I nodded all the way, and then the boss finished and asked me if I understood? I answered and understood what I was like.
I understand three points. The first is to use java to develop, the second is to support TCP and UDP protocols, and the other is controllable. So I started to design and research what is syslog log server.

preparation in advance

Here's what you need to prepare:

  1. A pair of healthy hands, can move;
  2. Compiler, ecplise or idea can be used, I use ecplise here;
  3. Syslog parses jar packages here using syslog4j jar packages, mvn project words maven address maven address Extraction code mve8 jar address
    Note: If your local maven project refers to Aliyun, you can change the version to 0.9.46, just like here I am.

    4. You need to understand what syslog is. Portal

Functional rendering

TCP Server and TCP Client Running Results:

TCP Server and TCP Client Running Results:

The results applied to the project:

Operation page:

Solution to the problem that the received data can only be output to the console

This problem has been bothering me for a long time, but I haven't found any solution. It's described in https://bbs.csdn.net/topics/392090474. You can copy the code on the first floor and try it out. The main problem is that the author of the jar package did not write out the method of data processing, and the run in this method directly prints out the information without giving any chance of operation. The solution is to implement the Syslog Server Session Event Handler IF interface in the jar package and then rewrite the event method inside. This interface provides many methods, which can be rewritten according to their own needs to achieve better results.

Specific code

Beep began to code for so long.
1.SyslogServerEventHandler class, which inherits SyslogServerSessionEventHandler IF and rewrites event method for operation and reception of information.

public class SyslogServerEventHandler implements SyslogServerSessionEventHandlerIF {//extends PrintStreamSyslogServerEventHandler {

	private String syslog ;
	
	//Rewriting event method
	public void event(Object session, SyslogServerIF syslogServer, SocketAddress socketAddress, SyslogServerEventIF event) {
		//Judging whether the transmission time exists or not, there is no setting the current time to the transmission time.
		String date = (event.getDate() == null ? new Date() : event.getDate()).toString();
		//At the generation end of the parsing log, 3 is to move the number left by three.
		String facility = SyslogUtility.getFacilityString(event.getFacility()<<3);
		//Speaking of the level of parsing logs, the higher the level, the lower the level
		String level = SyslogUtility.getLevelString(event.getLevel());
		//Get the current source device IP
		String sourceIP = getIPAddress(socketAddress.toString());
		//Access to the subject of information
		String msg = event.getMessage();
		//Put in information
		setSyslog("{" + facility + "} " + date + " " + level + " " + event.getMessage()+ " " +sourceIP );
		try {
			//Print information
			System.out.println(getSyslog());
		} catch (UnsupportedEncodingException e) {
			System.err.println("UnsupportedEncodingException");
		}
		
	}
	public String getSyslog() throws UnsupportedEncodingException {
		return new String(syslog.getBytes(),"UTF-8");
	}
	public void setSyslog(String syslog) {
		this.syslog = syslog;
	}
	//Get the ip address in the string
	private String getIPAddress(String bString)
	{
		String regEx="((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(bString);
		String result = "";
		while (m.find()) {
		result=m.group();
		
		break;  
		}
		return result;
	}
	
	
	@Override
	public void initialize(SyslogServerIF syslogServer) {}
	@Override
	public void destroy(SyslogServerIF syslogServer) {}
	@Override
	public Object sessionOpened(SyslogServerIF syslogServer, SocketAddress socketAddress) {return null;}
	@Override
	public void exception(Object session, SyslogServerIF syslogServer, SocketAddress socketAddress,Exception exception) {}
	@Override
	public void sessionClosed(Object session, SyslogServerIF syslogServer, SocketAddress socketAddress,boolean timeout) {}
}
  1. I like to start TCP servers in threaded mode, because I don't have to go back and forth.
public class TCPSyslogServerFinal implements Runnable {

	private static TCPSyslogServerFinal TCPSyslogServerFinal = null;
	//syslog server configuration file for server shutdown
	private SyslogServerIF serverIf = null ;
	
	public SyslogServerIF getServerIF() {
		return serverIf;
	}
	private void setServerIF(SyslogServerIF serverIF) {
		this.serverIf = serverIF;
	}
	
	private TCPSyslogServerFinal(){}
	//Write in singleton mode
	public static synchronized TCPSyslogServerFinal getTCPSyslogServer()
	{
		if(TCPSyslogServerFinal == null)
		{
			TCPSyslogServerFinal = new TCPSyslogServerFinal();
		}
		return TCPSyslogServerFinal;
	}
	@Override
	public void run() {
		//Instantiated reception processing method
		SyslogServerEventHandlerIF eventHandler = new SyslogServerEventHandler();
		//Incoming TCP Protocol Parameters Instantiate Specific Server
		SyslogServerIF serverIF = SyslogServer.getInstance("tcp");
		//Getting configuration information variables from the server
		SyslogServerConfigIF config = serverIF.getConfig();
		//Set the monitor address 0.0.0.0 as all the addresses in the monitor network
		config.setHost("0.0.0.0");
		//Set listener address 514, 514 to syslog default address
		config.setPort(514);
		//Put in receiving method
		config.addEventHandler(eventHandler);
		//initialize server
		serverIF.initialize("tcp",config);
		System.out.println("server start tcp");
		//Set server variables to close external calls
		setServerIF(serverIF);
		//Server startup
		serverIF.run();
	}
}
  1. UDP servers I like to start in a threaded way, but the difference is that UDP is the place where the transmission takes place.
public class UDPSyslogServerFinal implements Runnable {

	private static UDPSyslogServerFinal UDPSyslogServerFinal = null;
	//syslog server configuration file for server shutdown
	private SyslogServerIF serverIf = null ;
	
	public SyslogServerIF getServerIF() {
		return serverIf;
	}
	private void setServerIF(SyslogServerIF serverIF) {
		this.serverIf = serverIF;
	}
	
	private UDPSyslogServerFinal(){}
	//Write in singleton mode
	public static synchronized UDPSyslogServerFinal getUDPSyslogServer()
	{
		if(UDPSyslogServerFinal == null)
		{
			UDPSyslogServerFinal = newUDPSyslogServerFinal();
		}
		return UDPSyslogServerFinal;
	}
	@Override
	public void run() {
		//Instantiated reception processing method
		SyslogServerEventHandlerIF eventHandler = new SyslogServerEventHandler();
		//This is where the specific server is instantiated with UDP protocol parameters. If you are in trouble, you can optimize the algorithm by yourself and then combine the two into one.
		SyslogServerIF serverIF = SyslogServer.getInstance("udp");
		//Getting configuration information variables from the server
		SyslogServerConfigIF config = serverIF.getConfig();
		//Set the monitor address 0.0.0.0 as all the addresses in the monitor network
		config.setHost("0.0.0.0");
		//Set listener address 514, 514 to syslog default address
		config.setPort(514);
		//Put in receiving method
		config.addEventHandler(eventHandler);
		//initialize server
		serverIF.initialize("udp",config);
		System.out.println("server start udp");
		//Set server variables to close external calls
		setServerIF(serverIF);
		//Server startup
		serverIF.run();
	}
}

4. ClientClass on the client side. I like to implement it in threaded way.

public class ClientClass implements Runnable{
	//The end of the control cycle
	private boolean flag = true;
	private static ClientClass ClientClass = null;
	private ClientClass () {
	}
	public static synchronized ClientClass getClient()
	{
		if(ClientClass == null)
			ClientClass = new ClientClass ();
		return ClientClass ;
	}
	@Override
	public void run() {
		try {  
			//Initialization identifier bit
			flag = true;
			//Transfer instantiated protocol types in the form of transport names
			String prot = Thread.currentThread().getName();  
            //Get the operation class of syslog and use UDP protocol. Syslog supports "udp", "tcp", "unix_syslog", "unix_socket" protocols  
            SyslogIF syslog = Syslog.getInstance(prot);   
            //Set the syslog server address to your previous server address
            syslog.getConfig().setHost("xx.xx.xx.xx");  
            //Set syslog receiving port, default 514  
            syslog.getConfig().setPort(514);  
            //Splicing syslog logs
            String str = "operator Protocol "+ Thread.currentThread().getName();  
            System.out.println("+++++++++++++start++++++++++++");
            while(flag) {
            	//Level debug
	            syslog.log(SyslogConstants.LEVEL_DEBUG, URLDecoder.decode(str,"utf-8")); 
	            //Buffer time to program, no buffer time to receive data
	            Thread.sleep(100);
            }
           System.out.println(Thread.currentThread().getName()+" end");
        } catch (Exception e) { 
        	System.err.println("Error");
        	e.printStackTrace();
        } 
     }
     public void shutdown() {
		try {
			//Thread stop
			Thread.sleep(2000);
			//Change identification bit
			flag = false;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

5. Test class TestServerClass, test class running main method

@SuppressWarnings("unused")
public class TestServerClass implements Runnable{
	public static void main(String[] args) throws Exception {
		//Get UDP server threads
		Thread UDPServer = new Thread(UDPSyslogServerFinal.getUDPSyslogServer(),"This is UDP The server");
		//Get TCP server threads
		Thread TCPServer = new Thread(TCPSyslogServerFinal.getTCPSyslogServer(),"This is TCP The server");
		//Get UDP client threads
		Thread UDPClient = new Thread(ClientClass.getClient(),"UDP");
		//Get TCP client threads
		Thread TCPClient = new Thread(ClientClass.getClient(),"TCP");
		//Startup thread
		UDPServer.start();
		UDPClient.start();
		TCPServer.start();
		TCPClient.start();
		//Close after running for ten seconds
		Thread.sleep(10*1000);
		//Close the server
		UDPSyslogServerFinal.getUDPSyslogServer().getServerIF().shutdown();
		TCPSyslogServerFinal.getTCPSyslogServer().getServerIF().shutdown();
		//Close the client
		ClientClass.getClient().shutdown();
	}
}

epilogue

This is the end of the article. The original intention of writing this article is to help those who want to find the syslog server of java but can not find it. Really, trying to go to Baidu on the Internet and browsing blogs on various websites can not find a solution. This feeling is really collapsed. All my inspiration came from the post https://bbs.csdn.net/topics/392090474, which was not finished until I released it, so I intend to write out the solution and then finish that post, hoping to help those who read it.

Posted by Person on Tue, 30 Apr 2019 03:40:38 -0700