I think this decoder is related to camel-mina component, maybe we can put it into camel-mina component. BTW, we also have the camel-netty component, and netty is more active than mina, a netty version of syslog decoder could be more useful.

On 10/19/10 9:20 AM, Johan Edstrom wrote:
Something like this...

Writing the tests and the encoder right now...

/**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */

package org.apache.camel.component.syslog;

import java.net.InetSocketAddress;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public class SyslogDecoder extends ProtocolDecoderAdapter {

     private static final transient Log LOG = 
LogFactory.getLog(SyslogDecoder.class);

     private final SyslogMessage syslogMessage = new SyslogMessage();

     private static enum MONTHS {
         jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
     }

     private final static Map<String, MONTHS>  MONTH_VALUE_MAP = new 
HashMap<String, MONTHS>() {
         {
             put("jan", MONTHS.jan);
             put("feb", MONTHS.feb);
             put("mar", MONTHS.mar);
             put("apr", MONTHS.apr);
             put("may", MONTHS.may);
             put("jun", MONTHS.jun);
             put("jul", MONTHS.jul);
             put("aug", MONTHS.aug);
             put("sep", MONTHS.sep);
             put("oct", MONTHS.oct);
             put("nov", MONTHS.nov);
             put("dec", MONTHS.dec);
         }
     };

     public void decode(IoSession ioSession, ByteBuffer byteBuffer, 
ProtocolDecoderOutput protocolDecoderOutput) throws Exception {

         syslogMessage.setDestination((InetSocketAddress) 
ioSession.getLocalAddress());
         syslogMessage.setSource((InetSocketAddress) 
ioSession.getLocalAddress());
         syslogMessage.setRawMessage(byteBuffer.toString());

         //Rewind so we actually can parse this
         byteBuffer.rewind();

         Character charFound = (char) byteBuffer.get();

         while (charFound != '<') {
             //Ignore noise in beginning of message.
             charFound = (char) byteBuffer.get();
         }
         char priChar = 0;
         if (charFound == '<') {
             int facility = 0;

             while (Character.isDigit(priChar = (char) (byteBuffer.get()&  
0xff))) {
                 facility *= 10;
                 facility += Character.digit(priChar, 10);
             }
             syslogMessage.setFacility(SyslogFacility.values()[facility>>  3]);
             syslogMessage.setSeverity(SyslogSeverity.values()[facility&  
0x07]);
         }

         if (priChar != '>') {
             //Invalid character - this is not a well defined syslog message.
             LOG.error("Invalid syslog message, missing a>  in the Facility/Priority 
part");
         }

         //Done parsing severity and facility
         //<169>Oct 22 10:52:01 TZ-6 scapegoat.dmz.example.org 10.1.2.3 
sched[0]: That's All Folks!
         //Need to parse the date.

         /**
          The TIMESTAMP field is the local time and is in the format of "Mmm dd
          hh:mm:ss" (without the quote marks) where:

          Mmm is the English language abbreviation for the month of the
          year with the first character in uppercase and the other two
          characters in lowercase.  The following are the only acceptable
          values:

          Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

          dd is the day of the month.  If the day of the month is less
          than 10, then it MUST be represented as a space and then the
          number.  For example, the 7th day of August would be
          represented as "Aug  7", with two spaces between the "g" and
          the "7".

          hh:mm:ss is the local time.  The hour (hh) is represented in a
          24-hour format.  Valid entries are between 00 and 23,
          inclusive.  The minute (mm) and second (ss) entries are between
          00 and 59 inclusive.


          */

         char[] month = new char[3];
         for (int i = 0; i<  3; i++) {
             month[i] = (char) byteBuffer.get();
         }
         charFound = (char) byteBuffer.get();
         if (charFound != ' ') {
             //Invalid Message - missing mandatory space.
             LOG.error("Invalid syslog message, missing a mandatory space after 
month");
         }
         charFound = (char) byteBuffer.get();

         int day = 0;
         if (charFound == ' ') {
             //Extra space for the day - this is okay.
             //Just ignored per the spec.
         } else {
             day *= 10;
             day += Character.digit(charFound, 10);
         }

         while (Character.isDigit(charFound = (char) (byteBuffer.get()&  
0xff))) {
             System.out.println("Char " + charFound);
             day *= 10;
             day += Character.digit(charFound, 10);
         }

         int hour = 0;
         while (Character.isDigit(charFound = (char) (byteBuffer.get()&  
0xff))) {
             System.out.println("Hour " + charFound);
             hour *= 10;
             hour += Character.digit(charFound, 10);
         }

         int minute = 0;
         while (Character.isDigit(charFound = (char) (byteBuffer.get()&  
0xff))) {
             System.out.println("Hour " + charFound);
             minute *= 10;
             minute += Character.digit(charFound, 10);
         }

         int second = 0;
         while (Character.isDigit(charFound = (char) (byteBuffer.get()&  
0xff))) {
             System.out.println("Hour " + charFound);
             second *= 10;
             second += Character.digit(charFound, 10);
         }

         //The host is the char sequence until the next ' '

         StringBuilder host = new StringBuilder();
         while ((charFound = (char) (byteBuffer.get()&  0xff)) != ' ') {
             host.append(charFound);
         }

         StringBuilder msg = new StringBuilder();
         while (byteBuffer.hasRemaining()) {
             charFound = (char) (byteBuffer.get()&  0xff);
             msg.append(charFound);
         }

         //Insert a correct Date/Timestamp based on the parsing.
         //Add the message to the SyslogMessage Body.
         String parsedMonth = String.valueOf(month).toLowerCase();
         System.out.println("Paresed " + parsedMonth);
         System.out.println("Month number " + String.valueOf(month) + " " + 
MONTH_VALUE_MAP.get(parsedMonth));

         Calendar calendar = new GregorianCalendar();
         calendar.set(Calendar.MONTH, 
MONTH_VALUE_MAP.get((String.valueOf(month).toLowerCase())).ordinal());
         calendar.set(Calendar.DAY_OF_MONTH, day);
         calendar.set(Calendar.HOUR, hour);
         calendar.set(Calendar.MINUTE, minute);
         calendar.set(Calendar.SECOND, second);

         syslogMessage.setMessageTime(calendar.getTime());

         syslogMessage.setContent(msg.toString());
         if (LOG.isTraceEnabled()) {
             LOG.trace("Syslog message : " + syslogMessage.toString());
         }

         protocolDecoderOutput.write(syslogMessage);
     }


}


On Oct 16, 2010, at 8:55 PM, Willem Jiang wrote:

Hi Johan,

I guess you didn't past the link of you parser code :)

On 10/17/10 10:31 AM, Johan Edstrom wrote:
Gents!

Syslog, anyone have comments on this? I am writing a simple parser for 
Mina/Camel that I want to re-use in opennms. (A GPL Project)
  But I wanted to put the parsing parts here so it is ASF license. (I think it 
is stupid that all the parsers are GPL).
In an input if you look at the RFC mostly used, it is 99% best effort, would 
thinks like SyslogHeader.Priority be sufficient?


Johan Edstrom
[email protected]
They that can give up essential liberty to purchase a little temporary safety, 
deserve neither liberty nor safety.
Benjamin Franklin, Historical Review of Pennsylvania, 1759








--
Willem
----------------------------------
Open Source Integration: http://www.fusesource.com
Blog:    http://willemjiang.blogspot.com (English)
         http://jnn.javaeye.com (Chinese)
Twitter: http://twitter.com/willemjiang

Johan Edstrom

[email protected]

They that can give up essential liberty to purchase a little temporary safety, 
deserve neither liberty nor safety.

Benjamin Franklin, Historical Review of Pennsylvania, 1759








--
Willem
----------------------------------
Open Source Integration: http://www.fusesource.com
Blog:    http://willemjiang.blogspot.com (English)
         http://jnn.javaeye.com (Chinese)
Twitter: http://twitter.com/willemjiang

Reply via email to