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:
- A pair of healthy hands, can move;
- Compiler, ecplise or idea can be used, I use ecplise here;
-
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) {} }
- 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(); } }
- 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.