2016-03-04 3 views
0

У меня есть два файла журнала с разными форматами даты и времени, которые я хотел бы объединить.Слияние файлов журнала с различными форматами

Первый файл представляет собой стандартный Apache access_log файл следующим образом:

127.0.0.1 - - [29/февраля/2016: 16: 57: 52 -0600] «GET/приложение/WCS/апи/version? nodeRef = workspace: // SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0 HTTP/1.1 "200 567
127.0.0.1 - - [29/Feb/2016: 16: 57: 52 -0600]" GET/application/wcs/api/node/workspace/SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0/workflow-экземпляры HTTP/1.1 "200 40
127.0.0.1 - - [29/Feb/2016: 16: 57: 52 -0600] «GET/application/wcs/cisco/appId? UserId = abcdefg & requestType = get HTTP/1.1" 200 45
173.37.239.93 - abcdefg [29/Feb/2016: 16: 57: 52 -0600] «GET/share/page/site/nextgen-edcs/document-details? NodeRef = workspace: // SpacesStore/ecd62cfa-fd19 -4d6b-b45d-14f0e5b92cf0 HTTP/1.1 "200 124492
173.37.239.93 - abcdefg [29/Feb/2016: 16: 57: 53 -0600]" GET /share/service/messages_69bcdfdb058bb873ff49cc2a10c958b7.js?locale=en_US HTTP/1.1" 200 81698
173.37.239.93 - ABCDEFG [29/февраля/2016: 16: 57: 53 -0600] "GET /share/res/yui/history/history_543b42a00a378f4d4b6e70c81d915b0a.js HTTP/1.1" 200 5781

. , , где «abcdedfg» = userid.

Второй файл журнала отформатирован следующим образом:

2016-02-12 08: 16: 03630 WARN [cluster.cache.HazelcastSimpleCache] [HTTP-био-8443-Exec-212] Кластер неактивен, но put (k, v) был вызван для кеша HazelcastSimpleCache [cacheName = cache.readersSharedCache]
2016-02-12 08: 16: 03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212 ] Кластер неактивен, но get (key) был вызван для кеша HazelcastSimpleCache [cacheName = cache.readersSharedCache], key = AclEntity [ID = 1893033, версия = 55, aclId = 16cf5bc3-27d0-4d50-a93d-3bee1ddd112e, isLatest = true, aclVersion = 1, inherits = true, inheritsFrom = 1889292, type = 1, inheritedAcl = 1893034, isVersioned = false, requireVersion = false, aclChangeSet = 1451473]
2016-02-12 08: 16: 03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Кластер неактивен, но put (k, v) был вызван для кэша HazelcastSimpleCache [cacheName = cache.readersSharedCache]

Мои цели:

  1. конвертировать форматы даты/времени в первый файл журнала в формате даты/времени второго журнала файл
  2. сбивает IP-адреса из первого файла журнала, но сохраняет идентификаторы пользователя.
  3. объединить два файла журнала вместе
  4. сортировать по дате/времени.

Вот то, что я до сих пор -

$LOGFILE1 = "catalina.out"; 
$LOGFILE2 = "access_log"; 

open(LOGFILE1) or die("Could not open log file."); 
foreach $line (<LOGFILE1>) { 
    chomp($line); 
    if ($line =~ /^2016.+$/) { 
     print $line . "\n"; 
    } 
} 

open(LOGFILE2) or die("Could not open log file."); 
foreach $line (<LOGFILE2>) { 
chomp($line); 
if ($line =~ /\d{2}\/\S{3}\/\d{4}:\d{2}:\d{2}:\d{2} -\d{3}/) { 
print $line . "\n"; 
} 

    # format of file 1 
    # DD/MMM/YYYY:HH:MM:SS -NNNN 
    # 29/Feb/2016:20:03:07 -600 
    # format of file 2 
    # YYYY-MM-DD HH:MM:SS,NNN 
    # 2016-02-12 08:16:03,631 
} 

Так что я в основном интересуют только строки с датой/временем информация, поэтому приведенный выше код отбрасывая остальные строки.

Где я застрял:
1) как преобразовать формат даты/времени в файл 1 в формат данных/времени файла 2?
2) Меня не интересуют IP-адреса, но я хочу сохранить идентификаторы пользователей. Поскольку файл 1 не запускается с информацией о дате/времени, подобной файлу 2, после преобразования, как я буду сортировать по дате после слияния двух?

Любая помощь будет оценена!

+3

* Мы помогаем тем, кто помогает себе *. Что вы пробовали, пожалуйста, приложите некоторые усилия. –

+0

@anunsh - добавлен код, который у меня есть. – user9018

+0

Может быть сделано с использованием [DateTime :: Format :: Strptime] (https://metacpan.org/pod/DateTime::Format::Strptime). Вам понадобятся функции 2 функции [parse_datetime и format_datetime] (https://metacpan.org/pod/DateTime::Format::Strptime#strptime-parse_datetime-string). –

ответ

0

Решение проблемы с использованием Time::Piece. Я использовал Inline :: Files для имитации 2 файлов. Вы должны были бы открыть вам лога как

my $logfile1 = "catalina.out"; 
my $logfile2 = "access_log"; 


open my $log1_fh, '<', $logfile1 or die $1; 
open my $log2_fh, '<', $logfile2 or die $1; 

Программы будет выглядеть, как эта, который дал мне результаты, я думаю, вы хотите.

#!/usr/bin/perl 
use strict; 
use warnings; 
use Inline::Files; 
use Time::Piece; 

my %data; 

while (<FILE2>) { 
    # get date_time 
    my ($dt) = /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d),/ or next; 
    push @{ $data{$dt} }, $_; 
} 

my $format = '%d/%b/%Y:%H:%M:%S'; 

while (<FILE1>) { 
    /\[(\S+)/; 
    my $t = Time::Piece->strptime($1, $format) 
     or die "Cannot parse $1. $!"; 

    my $dt = $t->strftime('%Y-%m-%d %H:%M:%S'); 

    s/^\S+ (?:-)+//; 
    s/(?<=\[)[^\]]+/$dt/; 
    push @{ $data{$dt} }, $_; 
} 

for my $dt (sort keys %data) { 
    my $aref = $data{$dt}; 
    print for @$aref; 
} 


__FILE1__ 
127.0.0.1 - - [29/Feb/2016:16:57:52 -0600] "GET /application/wcs/api/version?nodeRef=workspace://SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0 HTTP/1.1" 200 567 
127.0.0.1 - - [29/Feb/2016:16:57:52 -0600] "GET /application/wcs/api/node/workspace/SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0/workflow-instances HTTP/1.1" 200 40 
127.0.0.1 - - [29/Feb/2016:16:57:52 -0600] "GET /application/wcs/cisco/appId?userId=abcdefg&requestType=get HTTP/1.1" 200 45 
173.37.239.93 - abcdefg [29/Feb/2016:16:57:52 -0600] "GET /share/page/site/nextgen-edcs/document-details?nodeRef=workspace://SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0 HTTP/1.1" 200 124492 
173.37.239.93 - abcdefg [29/Feb/2016:16:57:53 -0600] "GET /share/service/messages_69bcdfdb058bb873ff49cc2a10c958b7.js?locale=en_US HTTP/1.1" 200 81698 
173.37.239.93 - abcdefg [29/Feb/2016:16:57:53 -0600] "GET /share/res/yui/history/history_543b42a00a378f4d4b6e70c81d915b0a.js HTTP/1.1" 200 5781 
__FILE2__ 
2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but put(k,v) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache] 
2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but get(key) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache], key=AclEntity[ ID=1893033, version=55, aclId=16cf5bc3-27d0-4d50-a93d-3bee1ddd112e, isLatest=true, aclVersion=1, inherits=true, inheritsFrom=1889292, type=1, inheritedAcl=1893034, isVersioned=false, requiresVersion=false, aclChangeSet=1451473] 
2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but put(k,v) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache] 

Я использовал хэш %data для хранения строк. Ключ - это преобразованная дата, поэтому позже в программе вы можете распечатать их в отсортированном порядке.

Выход из этой программы:

2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but put(k,v) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache] 
2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but get(key) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache], key=AclEntity[ ID=1893033, version=55, aclId=16cf5bc3-27d0-4d50-a93d-3bee1ddd112e, isLatest=true, aclVersion=1, inherits=true, inheritsFrom=1889292, type=1, inheritedAcl=1893034, isVersioned=false, requiresVersion=false, aclChangeSet=1451473] 
2016-02-12 08:16:03,630 WARN [cluster.cache.HazelcastSimpleCache] [http-bio-8443-exec-212] Cluster is inactive but put(k,v) was called for cache HazelcastSimpleCache[cacheName=cache.readersSharedCache] 
[2016-02-29 16:57:52] "GET /application/wcs/api/version?nodeRef=workspace://SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0 HTTP/1.1" 200 567 
[2016-02-29 16:57:52] "GET /application/wcs/api/node/workspace/SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0/workflow-instances HTTP/1.1" 200 40 
[2016-02-29 16:57:52] "GET /application/wcs/cisco/appId?userId=abcdefg&requestType=get HTTP/1.1" 200 45 
abcdefg [2016-02-29 16:57:52] "GET /share/page/site/nextgen-edcs/document-details?nodeRef=workspace://SpacesStore/ecd62cfa-fd19-4d6b-b45d-14f0e5b92cf0 HTTP/1.1" 200 124492 
abcdefg [2016-02-29 16:57:53] "GET /share/service/messages_69bcdfdb058bb873ff49cc2a10c958b7.js?locale=en_US HTTP/1.1" 200 81698 
abcdefg [2016-02-29 16:57:53] "GET /share/res/yui/history/history_543b42a00a378f4d4b6e70c81d915b0a.js HTTP/1.1" 200 5781 
0

Пока я не буду писать сценарий для вас, общий сценарий должен выглядеть примерно так:

use strict; 
use warnings; 
use DateTime::Format::Strptime; 

sub firstFileLine { 
    # parse line as needed, and return a hash reference with 2 keys: 
    # 1. `line`: the contents of the line, possibly edited 
    # 2. `ts`: the UTC unix timestamp, via the DateTime::Format::Strptime module 
} 

sub secondFileLine { 
    # similar to `firstFileLine`, return a hash reference 
} 

my @firstLines = map { firstFileLine($_) } <FILE1>; 
my @secondLines = map { secondFileLine($_) } <FILE2>; 

my @sorted = map { $_->{line} } sort {$a->{ts} <=> $b->{ts}} (@firstLines, @secondLines); 

Прочитайте документацию на DateTime::Format::Strptime, map и sort. Вам повезло, что Perl является одним из самых хорошо документированных языков, пользуясь этим фактом!

Смежные вопросы