The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

RADIUS::XMLParser - Radius log file XML convertor

SYNOPSIS

            use RADIUS::XMLParser;
    
            
            my %labels = (
                    'Event-Timestamp' => 'Time', # name of tag "Event-Timestamp"
                    'User-Name' => 'User', # name of tag "User-Name"
                    'File' => '' # default name (i.e. File) for tag File
            );
            
            my $radius = RADIUS::XMLParser->new(
                    {
                            VERBOSE => 1,
                            DAYSFORORPHAN => 1,
                            AUTOPURGE => 0,
                            ALLEVENTS => 1,
                            OUTPUTDIR => '/tmp/',
                            MAP => \%labels
                    }
            );
            
            my ($xml, $stop, $start, $interim, $processed) = $radius->convert('radius.log');

DESCRIPTION

This module will extract and sort any radius events included into a radius log file.
Note that your logfile must contain an empty line at its end otherwise the last event will not be analyzed.
Events will be grouped by their session ID and converted into XML sessions.
At this time, supported events are the following:
                START
                INTERIM-UPDATE
                STOP

Any event will be stored on different hash (with SessionID as a unique key). Then, for each STOP event, the respective START and INTERIM event will be retrieved (based on same session ID)

[OPTIONAL] Each found START / INTERIM event will be written, final hash will be empty.
[OPTIONAL] Only the newest START / INTERIM events will be kept. Oldest ones will be considered as orphan events and will be dropped

Final XML will get the following structure:

        <?xml version="1.0" encoding="UTF-8"?>
        <sessions>
           <session sessionId=$sessionId>
              <start></start>
              <interims>
                 <interim id1></interim>
              </interims>
              <stop></stop>
           </session>
        </sessions>

CONSTRUCTOR

Usage:

        my $parser = RADIUS::XMLParser->new({%params});

Return:

A radius parser blessed reference

Parameters:

Hash reference including below Options

Options:

[optional] VERBOSE

Integer (0 by default) enabling verbose mode.
Regarding the amount of lines in a typical Radius log file (hundred MB large is the norm), verbose mode is split into several levels (0,1,2,3).

[optional] MAP

Hash reference of labels user would like to see converted into XML.
Hash Keys are the keys to look for on Radius side
Hash Values are the name of the XML tags that will be written (XML keys are alias of Radius keys)
Empty values will result on tag's name = radius keys
Note that some Radius keys might not be XML compliant (e.g. <3GPP-XYZ-etc...>). This key / value approach will avoid such XML constraint

A reference to below Array passed as an input parameter...

        my %map = (
          "Acct-Output-Packets" => "Output",
          "NAS-IP-Address" => "Address",
          "Event-Timestamp" => ""
        );

...will result on the following XML structure

        <stop>
                <Output></Output>
                <Address></Address>
                <Event-Timestamp></Event-Timestamp>
        </stop>
If MAP is not supplied, all the found Key / Values will be written.
Else, only the supplied keys / values will be written
FYI, Gettings few MAP is significantly faster... Might save precious time when dealing with large files !

[optional] AUTOPURGE

Boolean (0 by default) that will purge stored hash reference (Start + Interim) before being used for Event lookup.
Newest events will be kept, oldest will be dropped.
Threshold is defined by below parameter DAYSFORORPHAN

[optional] DAYSFORORPHAN

Number of days user would like to keep the orphan Start + Interim events.
Default is 1 day; any event older than 1 day will be dropped.
AUTOPURGE must be set to true

[optional] OUTPUTDIR

Output directory where XML file will be created
Default is first temporary directory (returned by File::Spec-tmpdir()>)

[optional] ALLEVENTS

Boolean (0 by default).
If 1, all events will be written, including Start, Interim and Stop "orphan" records. Note that Orphan hash should be empty after processing.
If 0, only the events Stop will be written together with the respective Start / Interims for the same session ID. Note that Orphan hash should not be empty after processing, and therefore should be written on disk (under ORPHANDIR directory)

[optional] XMLENCODING

Only utf-8 and us-ascii are supported
default is utf-8

[optional] ORPHANDIR

Default directory for orphan hash tables stored structure
Default is first temporary directory (returned by File::Spec-tmpdir()>)

METHODS

convert

Description:

The convert will parse and convert provided file $radius_file.
All its events will be retrieved, sorted and grouped by their unique sessionId.
Then, file will be converted into a XML format.

Usage:

        my ($xml, $stop, $start, $interim, $processed) = $parser->convert($radius_file);
        

Parameter:

$radius_file: Radius log file that will be parsed.

Return:

$xml: The name of the XML file that has been created.
$stop: The number of STOP event written
$start: The number of START event written
$interim: The number of INTERIM event written
$processed: The number of processed lines in the original Radius log file

flush

Description:

The flush method will cleanup orphanage on demand
Note that this process is already done at startup but might be required some times to times, especially for deamons processes which might never have to rebuild parser (new method)
Oldest orphans are dropped
Need PURGEORPHAN parameter set (optionnally DAYSFORORPHAN)

Usage:

            $parser->flush();
            

EXAMPLE:

        use RADIUS::XMLParser;
        
        my $radius_file = 'radius.log';
        my %map = (
          "NAS-User-Name" => "User-Name",
          "Event-Timestamp"     => "",
          "File" => "File"
        );
        
        my $radius = RADIUS::XMLParser->new(
                {
                        VERBOSE       => 1,
                        DAYSFORORPHAN => 1,
                        AUTOPURGE     => 0,
                        ALLEVENTS     => 1,
                        XMLENCODING   => "utf-8",
                        OUTPUTDIR     => '/tmp/',
                        MAP               => \%map
                }
        );
        
        my ($xml, $stop, $start, $interim, $processed) = $radius->convert($radius_file);
        

Here is how the generated XML file will look like

        <?xml version="1.0" encoding="UTF-8"?>
        <session sessionId="d537cca0d43c95dc">
          <start>
           <Event-Timestamp>1334560899</Event-Timestamp>
           <User-Name>User1</User-Name>
           <File>radius.log</File>
          </start>
          <interims>
           <interim id="1">
            <Event-Timestamp>1334561024</Event-Timestamp>
            <User-Name>User1</User-Name>
            <File>radius.log</File>
           </interim>
           <interim id="2">
            <Event-Timestamp>1334561087</Event-Timestamp>
            <User-Name>User1</User-Name>
            <File>radius.log</File>
           </interim>
          </interims>
          <stop>
           <Event-Timestamp>1334561314</Event-Timestamp>
           <User-Name>User1</User-Name>
           <File>radius.log</File>
          </stop>
         </session>

AUTHOR

Antoine Amend <amend.antoine@gmail.com>

MODIFICATION HISTORY

See the Changes file.

COPYRIGHT AND LICENSE

Copyright (c) 2013 Antoine Amend. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.