wiki:KrakenFilterTutorial

Kraken Filter Tutorial

This tutorial will show you how to make kraken filter that receives syslog. This tutorial based on kraken-filter 1.0.1.

Create Kraken Bundle Project

mvn archetype:generate \
-DarchetypeGroupId=org.krakenapps \
-DarchetypeArtifactId=kraken-template \
-DarchetypeVersion=1.0.0 \
-DgroupId=org.krakenapps \
-DartifactId=kraken-syslog \
-Dversion=1.0.0
-DpackageName=org.krakenapps.syslog

Setup POM

  • For this tutorial:
    • Fix <name>$YOUR_PROJECT_NAME</name>
    • Add kraken-filter dependency to dependencies.
    • Remove <Private-Package>YOUR_PRIAVE_PACKAGES</Private-Package>
    • Remove <Import-Package>*</Import-Package>
    • Fix <Export-Package>*</Export-Package>
  • Use this:
    <project>
    ...
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>1.4.3</version>
            <extensions>true</extensions>
            <configuration>
              <instructions>
                <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
                <Export-Package>org.krakenapps.syslog</Export-Package>
              </instructions>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-ipojo-plugin</artifactId>
            <executions>
              <execution>
                <goals>
                  <goal>ipojo-bundle</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    ...
      <dependencies>
      	<dependency>
      		<groupId>org.krakenapps</groupId>
      		<artifactId>kraken-filter</artifactId>
      		<version>1.0.1</version>
      		<type>bundle</type>
      	</dependency>
      	<dependency>
      		<groupId>org.krakenapps</groupId>
      		<artifactId>kraken-api</artifactId>
      		<version>1.0.0</version>
      	</dependency>
      </dependencies>
    ...
    </project>
    

Create Filter Class

  • Click "New Java Class", create SyslogReceiver and extend org.krakenapps.filter.ActiveFilter.
  • Press Alt+Shift+S-V in eclipse and override like below:
    package org.krakenapps.syslog;
    
    import org.krakenapps.filter.ActiveFilter;
    import org.krakenapps.filter.Message;
    import org.krakenapps.filter.MessageSpec;
    
    public class SyslogReceiver extends ActiveFilter {
    
    	@Override
    	public void open() throws ConfigurationException {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void close() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public MessageSpec getOutputMessageSpec() {
    		// TODO Auto-generated method stub
    		return null;
    	}
    }
    

Define Message Specification

  • Implement getOutputMessageSpec()
    • We'll use "kraken.syslog" as name of message specification. (1.0 version)
    • "kraken.syslog" message will contain following fields:
      • date: received time. java.util.Date type
      • message: decoded text string. String type.
      • remote_ip: remote ip address, InetAddress type.
      • remote_port: remote udp port, Integer type.
      • local_ip: local ip address, InetAddress type.
      • local_port: local udp port, Integer type.
    • Decoder will be set by setProperty.
  • This filter will not receive any message. No input message spec needed.
  • Code:
    @Override
    public MessageSpec getOutputMessageSpec() {
    	return new DefaultMessageSpec("kraken.syslog", 1, 0);
    }
    

Preprocess and Postprocess

  • ActiveFilter should implement open() and close() methods.
    • open() will be called before run()
    • close() will be called after run()
  • open()
    • Bind to specified syslog port and set timeout to 1sec.
      address = InetAddress.getByName((String) getProperty("address"));
      server_port = Integer.parseInt((String) getProperty("port"));
      if (server_port == 0)
      	server_port = DEFAULT_SYSLOG_PORT;
      
      System.out.println("Port: " + server_port);
      System.out.println("Address: " + address.toString());
      
      socket = new DatagramSocket(server_port, address);
      socket.setSoTimeout(1000);
      
      buffer = new byte[1024];
      
  • close()
    socket.close();
    

Implement run() method

DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
	socket.receive(packet);

	packet.getData();
	MessageBuilder b = new MessageBuilder(getOutputMessageSpec());
	b.set("date", new Date());
	b.set("remote_ip", packet.getAddress());
	b.set("remote_port", new Integer(packet.getPort()));
	b.set("local_ip", address);
	b.set("local_port", new Integer(server_port));
	b.set("message", new String(packet.getData(), 0, packet.getLength(), charsetName));
	Message message = b.build();
	filterChain.process(message);

	logger.debug((String) message.get("message"));
} catch (SocketTimeoutException e) {
} catch (Exception e) {
	logger.warn("syslog receive error:", e);
}
  • Message is invariant, so MessageBuilder prepare all required data and instantiate Message only once.
  • You should call filterChain.process(message) to pass a message to chained filters.

Setup metadata

<ipojo xmlns:filter="org.krakenapps.filter.FilterHandler">
	<component classname="org.krakenapps.syslog.SyslogReceiver"
		immediate="true" architecture="true">
		<provides />
		<filter:filter />
	</component>
</ipojo>

Deploy

  • Package
    • mvn package
  • Install bundle from local filesystem and load filter at kraken console
    • Type "bundle.install  file:///C:/ProjectDirectory/target/kraken-syslog-1.0.0.jar
    • Type "filter.list" and see "org.krakenapps.syslog.SyslogReceiver"
    • Type "filter.load org.krakenapps.syslog.SyslogReceiver syslog"
    • Type "filter.status" then you can see "syslog" filter instance loaded.
    • Type "filter.set syslog address LOCAL_IP"
    • Type "filter.set syslog port 514"
    • Type "filter.run syslog 0", 0 means sleep time at each turn.
  • Test
    • Send syslog message and you can see syslog message in shell (or command prompt)
    • If you don't know any script language, use below python script
      $ python
      >>> from socket import *
      >>> s = socket(AF_INET, SOCK_DGRAM)
      >>> s.sendto('hello', ('YOUR_IP', 514))
      

Download