सवाल क्या आपके पास अपाचे लॉग को पार्स करने के लिए कोई उपयोगी अजीब और grep स्क्रिप्ट है? [बन्द है]


मैं लॉग विश्लेषकों का उपयोग कर सकता हूं, लेकिन इस समय क्या हो रहा है यह देखने के लिए मुझे हाल ही में वेब लॉग का विश्लेषण करना होगा।

मैं कभी-कभी ऐसी चीजें करता हूं जो शीर्ष 10 आईपीएस को समझते हैं जो एक निश्चित फ़ाइल का अनुरोध करते हैं

cat foo.log | grep request_to_file_foo | awk '{print $1}' |  sort -n | uniq -c | sort -rn | head

आपके टूलबॉक्स में आपके पास क्या है?


63
2018-05-21 22:14


मूल


मेरे पास वास्तव में यह बड़ा सुंदर रेगेक्स था जिसे मैंने हाथ से लिखा था ताकि मेरे सभी अपाचे कस्टम लॉग को अलग-अलग फ़ील्ड में डेटाबेस में जमा करने के लिए पार्स किया जा सके। मैं खुद को लात मार रहा हूं कि मेरे पास अब और नहीं है। यह एक लाइनर था; आपको प्रत्येक लॉग तत्व के लिए एक चर वापस दिया - तो मैं MySQL में डालने वाला था। अगर मुझे लगता है तो मैं इसे यहां पोस्ट करूंगा। - Kyle Hodgson


जवाब:


आप अकेले अजीब लॉग फ़ाइलों के साथ बहुत कुछ कर सकते हैं। अपाचे लॉग फाइल मूल रूप से व्हाइटस्पेस अलग होती हैं, और आप उद्धरण दिखा सकते हैं कि उद्धरण मौजूद नहीं हैं, और कॉलम संख्या द्वारा आपकी रुचि रखने वाली किसी भी जानकारी तक पहुंच सकते हैं। यह टूटने का एकमात्र समय यह है कि यदि आपके पास संयुक्त लॉग प्रारूप है और उपयोगकर्ता एजेंटों में रुचि है, तो उस बिंदु पर आपको उद्धरण (") को विभाजक के रूप में उपयोग करना होगा और एक अलग अजीब कमांड चलाएं। निम्नलिखित आपको आईपी दिखाएंगे प्रत्येक उपयोगकर्ता जो हिट की संख्या से क्रमबद्ध इंडेक्स पेज का अनुरोध करता है:

awk -F'[ "]+' '$7 == "/" { ipcount[$1]++ }
    END { for (i in ipcount) {
        printf "%15s - %d\n", i, ipcount[i] } }' logfile.log

$ 7 अनुरोधित यूआरएल है। आप शुरुआत में जो भी परिस्थितियां चाहते हैं उसे जोड़ सकते हैं। जो भी जानकारी आप चाहते हैं उसके साथ '$ 7 == "/" बदलें।

यदि आप $ 1 को प्रतिस्थापित करते हैं (ipcount [$ 1] ++), तो आप परिणामों को अन्य मानदंडों से समूहित कर सकते हैं। $ 7 का उपयोग करने से पता चलता है कि किन पृष्ठों को एक्सेस किया गया था और कितनी बार। बेशक आप शुरुआत में स्थिति बदलना चाहते हैं। निम्नलिखित दिखाएंगे कि किसी उपयोगकर्ता द्वारा किसी विशिष्ट आईपी से किन पृष्ठों को एक्सेस किया गया था:

awk -F'[ "]+' '$1 == "1.2.3.4" { pagecount[$7]++ }
    END { for (i in pagecount) {
        printf "%15s - %d\n", i, pagecount[i] } }' logfile.log

परिणामों को क्रम में प्राप्त करने के लिए, या तो शेल कमांड के हिस्से के रूप में, या अजीब स्क्रिप्ट में भी आउटपुट के माध्यम से आउटपुट को पाइप कर सकते हैं:

awk -F'[ "]+' '$7 == "/" { ipcount[$1]++ }
    END { for (i in ipcount) {
        printf "%15s - %d\n", i, ipcount[i] | sort } }' logfile.log

उत्तरार्द्ध उपयोगी होगा यदि आपने अन्य जानकारी प्रिंट करने के लिए अजीब स्क्रिप्ट का विस्तार करने का निर्णय लिया है। यह सब कुछ है कि आप क्या खोजना चाहते हैं। जो कुछ भी आप चाहते हैं उसके लिए इन्हें शुरुआती बिंदु के रूप में कार्य करना चाहिए।


53
2018-06-03 02:21



हाँ, पागल लंबी बिल्ली / grep / awk पाइपलाइनों को देखने के लिए यह हमेशा अजीब लगता है। एक बार जब आप अजीब हो जाते हैं, तो आमतौर पर यह पर्याप्त होता है। मूल पोस्ट के पहले तीन खंडों को "awk '/ request_to_file_foo / {print $ 1}' foo.log" के रूप में छोटा रूप से लिखा जा सकता है। अजीब इनपुट के रूप में एक फाइल ले सकते हैं, और यह जानने के लिए कि कौन सी लाइनों की देखभाल करने के लिए रेगेक्स का उपयोग कर सकते हैं। - Zac Thompson
सुरुचिपूर्ण और सरल। अच्छा। - Olivier Dulac
सावधान रहें, "लेखक" (3) फ़ील्ड में रिक्त स्थान की अनुमति है, जो सबकुछ तोड़ती है, और मुझे व्यक्तिगत रूप से लगता है कि इसे प्रतिबंधित करने के लिए इसे प्रतिबंधित किया जाना चाहिए ;-) - Mandark


एक चीज जिसे मैंने कभी और नहीं देखा है, जिन कारणों से मैं कल्पना नहीं कर सकता, अपाचे लॉग फ़ाइल प्रारूप को वास्तव में आपके लिए महत्वपूर्ण जानकारी के साथ एक अधिक आसानी से पारदर्शी संस्करण में बदलना है।

उदाहरण के लिए, हम कभी भी HTTP मूल लेख का उपयोग नहीं करते हैं, इसलिए हमें उन फ़ील्ड को लॉग इन करने की आवश्यकता नहीं है। मैं कर रहा हूँ प्रत्येक अनुरोध में कितना समय लगेगा, इस बारे में दिलचस्पी है, इसलिए हम इसे जोड़ देंगे। एक प्रोजेक्ट के लिए, हम भी जानना चाहते हैं (हमारे लोड बैलेंसर पर) यदि कोई सर्वर दूसरों की तुलना में धीमे अनुरोधों की सेवा कर रहा है, तो हम नाम का नाम लॉग करते हैं सर्वर हम वापस प्रॉक्सी कर रहे हैं।

यहां एक सर्वर की अपाचे कॉन्फ़िगरेशन से एक अंश दिया गया है:

# We don't want to log bots, they're our friends
BrowserMatch Pingdom.com robot

# Custom log format, for testing
#
#         date          proto   ipaddr  status  time    req     referer         user-agent
LogFormat "%{%F %T}t    %p      %a      %>s     %D      %r      %{Referer}i     %{User-agent}i" standard
CustomLog /var/log/apache2/access.log standard env=!robot

आप वास्तव में इससे क्या नहीं कह सकते हैं कि प्रत्येक फ़ील्ड के बीच एक शाब्दिक टैब वर्ण (\ t) है। इसका मतलब है कि अगर मैं पायथन में कुछ विश्लेषण करना चाहता हूं, उदाहरण के लिए गैर-200 स्थितियां दिखाएं, तो मैं यह कर सकता हूं:

for line in file("access.log"):
  line = line.split("\t")
  if line[3] != "200":
    print line

या अगर मैं 'छवियों को हॉटलिंक कर रहा हूं' करना चाहता हूं? यह होगा

if line[6] in ("","-") and "/images" in line[5]:

आईपी ​​के लिए एक्सेस लॉग में गिना जाता है, पिछला उदाहरण:

grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" logfile | sort -n | uniq -c | sort -n

ऐसा कुछ बन जाता है:

cut -f 3 log | uniq -c | sort -n

पढ़ने और समझने में आसान, और बहुत कम कम्प्यूटेशनल रूप से महंगा (कोई regex) जो 9 जीबी लॉग पर, कितना समय लगता है में एक बड़ा अंतर बनाता है। जब यह वास्तव में साफ हो जाता है तो यदि आप उपयोगकर्ता-एजेंटों के लिए एक ही काम करना चाहते हैं। यदि आपके लॉग स्पेस-सीमांकित हैं, तो आपको हाथ से कुछ नियमित अभिव्यक्ति मिलान या स्ट्रिंग करना होगा। इस प्रारूप के साथ, यह आसान है:

cut -f 8 log | uniq -c | sort -n

बिल्कुल उपरोक्त के समान ही। वास्तव में, आप जो भी सारांश करना चाहते हैं वह अनिवार्य रूप से वही है।

पृथ्वी पर क्यों मैं अपने सिस्टम के सीपीयू को अजीब और grep पर खर्च करूंगा जब कटौती ठीक से करेगी जो मैं तीव्रता के आदेश चाहता हूं?


23
2018-06-05 21:46



नए प्रारूप के लिए आपके उदाहरण वास्तव में अभी भी जटिल हैं - आईपी गणना बन जाती है cut -f 3 log | uniq -c | sort -n, उपयोगकर्ता एजेंट cut -f 8 log | uniq -c | sort -n। - Creshal
तुम सही हो, यह आसान है। मैंने इसे प्रतिबिंबित करने के लिए उदाहरण अपडेट किए हैं। - Dan Udey
"बिल्ली फ़ाइल | grep string" बेकार है, क्यों नहीं "grep स्ट्रिंग फ़ाइल"? - c4f4t0r
मुझे कोई बहाना नहीं है, और तदनुसार उदाहरण अपडेट किया है। - Dan Udey


अजीब और grep के बारे में भूल जाओ। चेक आउट asql। जब आप logfile से पूछताछ के लिए सिंटैक्स की तरह एसक्यूएल का उपयोग कर सकते हैं तो अपठनीय स्क्रिप्ट क्यों लिखें। उदाहरण के लिए।

asql v0.6 - type 'help' for help.
asql> load /home/skx/hg/engaging/logs/access.log
Loading: /home/skx/hg/engaging/logs/access.log
sasql> select COUNT(id) FROM logs
46
asql> alias hits SELECT COUNT(id) FROM logs
ALIAS hits SELECT COUNT(id) FROM logs
asql> alias ips SELECT DISTINCT(source) FROM logs;
ALIAS ips SELECT DISTINCT(source) FROM logs;
asql> hits
46
asql> alias
ALIAS hits SELECT COUNT(id) FROM logs
ALIAS ips SELECT DISTINCT(source) FROM logs;

14
2018-06-05 02:22



दिलचस्प है, लेकिन यदि आपके लॉग विशेष रूप से बड़े हैं तो मुझे समस्याएं हो सकती हैं। कस्टम लॉग प्रारूपों के साथ यह कितनी अच्छी तरह से सामना करता है? - Vagnerr
मैं इस समय कोशिश कर रहा हूं, लोड समय इतना धीमा है (कम से कम संस्करण 0.9 में)। एक 200 एमबी लॉग लोड हो रहा है जिसमें यह पांच मिनट से अधिक समय ले रहा है .. - Aseques
मुझे कहना होगा कि लोड समय के बाद (इसमें लगभग 15 मिनट लग गए) इस कार्यक्रम का सिंकस्टैक्स बहुत अच्छा है, आप सॉर्ट, गिन और ग्रुप कर सकते हैं। बहुत अच्छे। - Aseques
अपाचे HTTPD में एक विधि है जिसके साथ आप डेटाबेस को प्रभावी रूप से लॉग भेज सकते हैं। हां, लिखने में काफी समय लग सकता है, लेकिन एक थ्रेडेड प्रॉक्सी मध्य में सैंडविच की सही चीज़ कर सकती है। किसी भी तरह, जो एक एसक्यूएल में पूछताछ लॉग को सिंटैक्स की तरह बहुत तेज़ी से बना देगा। कोई लोडिंग भी शामिल नहीं है - डेटाबेस सर्वर हमेशा "चालू" होता है। - nearora


हाल ही में एन लॉग प्रविष्टियों से शीर्ष यूआरएल, शीर्ष रेफरर और शीर्ष उपयोगकर्ताेंट ढूंढने के लिए यहां एक स्क्रिप्ट है

#!/bin/bash
# Usage
# ls-httpd type count
# Eg: 
# ls-httpd url 1000
# will find top URLs in the last 1000 access log entries
# ls-httpd ip 1000
# will find top IPs in the last 1000 access log entries
# ls-httpd agent 1000
# will find top user agents in the last 1000 access log entries

type=$1
length=$2

if [ "$3" == "" ]; then
  log_file="/var/log/httpd/example.com-access_log"
else
  log_file="$3"
fi

if [ "$type" = "ip" ]; then
  tail -n $length $log_file | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort -n | uniq -c | sort -n
elif [ "$type" = "agent" ]; then
  tail -n $length $log_file | awk -F\" '{print $6}'| sort -n | uniq -c | sort -n
elif [ "$type" = "url" ]; then
  tail -n $length $log_file | awk -F\" '{print $2}'| sort -n | uniq -c | sort -n
fi

स्रोत


6
2017-11-27 14:03





आईपी ​​के लिए एक एक्सेस लॉग में गिना जाता है:

cat log | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort -n | uniq -c | sort -n

यह थोड़ा बदसूरत है, लेकिन यह काम करता है। मैं netstat (सक्रिय कनेक्शन देखने के लिए) के साथ निम्नलिखित का भी उपयोग करता हूं:

netstat -an | awk '{print $5}' | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | egrep -v "(`for i in \`ip addr | grep inet |grep eth0 | cut -d/ -f1 | awk '{print $2}'\`;do echo -n "$i|"| sed 's/\./\\\./g;';done`127\.|0\.0\.0)" | sort -n | uniq -c | sort -n

वे मेरे कुछ पसंदीदा "एक लाइनर" हैं :)


4
2018-05-22 02:19





इस प्रश्न के उत्तर के लिए सामान्य प्रश्नों की एक सूची बनाना एक महान सूचकांक होगा। मेरे सामान्य प्रश्न हैं:

  • हिट्रेट क्यों बदल गया?
  • समग्र प्रतिक्रिया समय क्यों बढ़ रहा है? '।

मैं सर्वर-स्टेटस पेजों (mod_status के माध्यम से) की निगरानी करके ऐसे परिवर्तनों को नोटिस करता हूं सक्रिय और हाल ही में किए गए अनुरोधों के लिए हिट्रेट और अनुमानित प्रतिक्रिया समय (पूरी तरह से जानते हुए कि मुझे डेटा का एक बड़ा ढेर याद आती है, लेकिन नमूने काफी अच्छे हैं)।

मैं निम्नलिखित लॉगफॉर्मेट निर्देश का उपयोग करता हूं (% टी वास्तव में उपयोगी है)

LogFormat "%h %l %u %t \"%r\" %>s %b 
    \"%{Referer}i\" \"%{User-Agent}i\" %T" custom

मैं कारण प्रभाव की तलाश में हूं और पहले क्या हुआ ... आम तौर पर मेरे लॉग में पैटर्न के विशिष्ट सबसेट के बारे में, तो मुझे किसी भी दिए गए पैटर्न / नियमित अभिव्यक्ति के लिए निम्न को जानने की आवश्यकता है:

  • किसी दिए गए पैटर्न (आईपी एड्रेस या सीजीआई स्ट्रिंग या पैरामीटर इत्यादि) के लिए प्रति अंतराल (मिनट या घंटा) हिटकेउंट्स
  • अनुमानित प्रतिक्रिया समय के हिस्टोग्राम (% टी पैरामीटर का उपयोग करके)

मैं आम तौर पर perl का उपयोग करता हूं, क्योंकि अंत में यह सार्थक होने के लिए पर्याप्त जटिल हो जाता है।


एक गैर-पर्ल उदाहरण गैर-200 स्थिति कोड के लिए प्रति मिनट एक त्वरित हिट्रेट होगा:

tail -9000 access_log | grep -v '" 200 ' | cut -d: -f2,3 | uniq -c

हां, मैं उस grep के साथ धोखा दे रहा हूं, एक उद्धरण-स्थान-200-स्पेस मैचों को केवल http स्टेटस कोड मानता हूं .... क्षेत्र को अलग करने के लिए अजीब या पर्ल का उपयोग कर सकते हैं, बस ध्यान रखें कि यह गलत हो सकता है।


एक पैटर्न के लिए हिट्रेट में बदलाव को देखने के लिए पर्ल में एक और जटिल उदाहरण हो सकता है।

नीचे लिपि में चबा करने के लिए बहुत कुछ है, खासकर यदि आप perl के साथ असहनीय हैं।

  • stdin पढ़ता है ताकि आप अपने लॉग के हिस्सों का उपयोग कर सकें, पूंछ का उपयोग करें (विशेष रूप से tail -f के साथ), greps और अन्य फ़िल्टरिंग के साथ या बिना ...
  • एक regex के हैक के साथ epot timestamp निष्कर्षण धोखा देती है और तिथि :: मैनिप का उपयोग
  • आप इसे प्रतिक्रिया समय या अन्य मनमाना डेटा निकालने के लिए केवल थोड़ा ही संशोधित कर सकते हैं

कोड निम्नानुसार है:

#!/usr/bin/perl
# script to show changes in hitrates for any regex pattern
# results displayed with arbitrary intervals
# and ascii indication of frequency
# gaps are also displayed properly
use Date::Manip;
use POSIX qw(strftime);
$pattern=shift || ".";
$ival=shift || 60;
$tick=shift || 10;
$minb=undef;
while (<>){
    next unless /$pattern/;
    $stamp="$1 $2" if m[(../.../....):(..:..:..)];
    $epoch = UnixDate(ParseDate($stamp),"%s");
    $bucket= int($epoch/$ival)*$ival;
    $minb=$bucket if $bucket<$minb || !defined($minb);
    $maxb=$bucket if $bucket>$maxb;
    $count{$bucket}++;
}
# loop thru the min/max range to expose any gaps
for($t=$minb;$t<=$maxb;$t+=$ival){
    printf "%s %s %4d %s\n",
            $t,
            strftime("%m/%d/%Y %H:%M:%S",localtime($t)),
            $count{$t}+0,
            substr("x"x100,0,$count{$t}/$tick
    );
}

यदि आप मानक मीट्रिक, चेकआउट को संसाधित करना चाहते हैं

  • अपने सभी लॉग एक साथ प्राप्त करने के लिए 'mergelog' (यदि आपके पास लोड बैलेंसर के पीछे एकाधिक अपाचे हैं) और
  • वेबलाइज़र (या awstats या अन्य आम विश्लेषक)।

3
2018-06-05 21:34





यहां मेरा 'sed' उदाहरण है, यह अपाचे लॉग के डिफ़ॉल्ट प्रारूप को पढ़ता है और इसे स्वचालित प्रसंस्करण के लिए कुछ और सुविधाजनक में परिवर्तित करता है। पूरी रेखा को नियमित अभिव्यक्ति के रूप में परिभाषित किया जाता है, चर को सहेजा जाता है और विभाजक के रूप में '#' के साथ आउटपुट में लिखा जाता है।

इनपुट की सरलीकृत नोटेशन है: % s% s% s [% s] "% s"% s% s "% s" "% s"

उदाहरण इनपुट लाइन: xx.xx.xx.xx - - [2 9 / मार्च / 2011: 12: 33: 02 +0200] "प्राप्त करें /index.html HTTP / 1.0" 200 9 443 "-" "मोज़िला / 4.0"

उदाहरण आउटपुट लाइन: xx.xx.xx.xx # - # - # 2 9 / मार्च / 2011: 12: 33: 02 + 0200 # GET /index.html HTTP / 1.0 # 200 # 9443 # - # मोज़िला / 4.0

cat access.log | \ 
  sed 's/^\(.*\) \(.*\) \(.*\) \[\(.*\)\] \"\(.*\)\" \(.*\) \(.*\) \"\(.*\)\" \"\(.*\)\"$/\1#\2#\3#\4#\5#\6#\7#\8#\9/g'

नियमित अभिव्यक्तियों की शक्ति महसूस करें :-)


3
2018-03-29 15:40



इसने एडब्ल्यूके के साथ एक हवा प्रसंस्करण किया। एक आम deliminator स्थापित करने के लिए एक त्वरित तरीका की तलाश में था और यह इसे दबाया। - Citricguy
मैंने रेगेक्स पावर महसूस किया है और बस अपने स्वयं के ट्विक के साथ गुजरना चाहता था, जो "एचटीएमएल / 1.1" को काटता है और प्रोटोकॉल को अलग करता है (शायद गैर मानक मानकों में) अपने क्षेत्र में। आनंद लें: `` `cat access.log | sed's /^(.*) (। *) (। *) [(। *)] \ "([[: अल्फा:]] \ +) (। *) HTTP \ / 1 \ .1 \" ( । *) (। *) \ "(। *) \" \ "(। *) \" $ / \ 1 # \ 2 # \ 3 # \ 4 # \ 5 # \ 6 # \ 7 # \ 8 # \ 9 # \ 10 / जी '`` `` - Josh Rumbut


मैं फ़ाइल को tailing या cating द्वारा बहुत बहुत उपयोग करते हैं। प्रत्येक रात मैं प्रत्येक सर्वर के लिए खुद को एक वेब रिपोर्ट प्रदान करता हूं। आपकी लॉग फ़ाइल और आपके लॉगफॉर्मैट के आधार पर आपको अपने लिए काम करने के लिए कुछ लाइनर संपादित करना होगा ..।

यहां एक साधारण उदाहरण दिया गया है:

अगर मैं केवल 404/500 स्टेटस कोड के लिए अपने सर्वर पर लॉग को पूंछ करना चाहता हूं तो मैं यह करूँगा:

# $6 is the status code in my log file

tail -f ${APACHE_LOG} |  awk  '$8 ~ /(404|500)/ {print $6}'

<स्निप>

echo ""
#echo  "Hits by source IP:"
echo "======================================================================"

awk '{print $2}' "$1" | grep -ivE "(127.0.0.1|192.168.100.)" | sort | uniq -c | sort -rn | head -25

echo ""
echo ""
#echo "The 25 most popular pages:"
echo "======================================================================"

awk '{print $6}' "$1" | grep -ivE '(mod_status|favico|crossdomain|alive.txt)' | grep -ivE '(.gif|.jpg|.png)' | \
 sed 's/\/$//g' | sort | \
 uniq -c | sort -rn | head -25

echo ""    
echo ""
echo "The 25 most popular pages (no js or css):"
echo "======================================================================"

awk '{print $6}' "$1" | grep -ivE '(mod_status|favico|crossdomain|alive.txt)' | grep -ivE '(.gif|.jpg|.png|.js|.css)' | \
 sed 's/\/$//g' | sort | \
   uniq -c | sort -rn | head -25

   echo ""


#echo "The 25 most common referrer URLs:"
echo "======================================================================"

awk '{print $11}' "$1" | \
 grep -vE "(^"-"$|/www.$host|/$host)" | \
 sort | uniq -c | sort -rn | head -25

echo ""

#echo "Longest running requests"
echo "======================================================================"

awk  '{print $10,$6}' "$1" | grep -ivE '(.gif|.jpg|.png|.css|.js)'  | awk '{secs=0.000001*$1;req=$2;printf("%.2f minutes req time for %s\n", secs / 60,req )}' | sort -rn | head -50

exit 0

</ स्निप>


2
2017-11-19 03:19





आपकी छवियों को गर्म-लिंक कौन कर रहा है:

awk -F\" '($2 ~ /\.(jpg|gif)/ && $4 !~ /^http:\/\/www\.mydomain\.com/){print $4}' access_log | sort | uniq -c | sort

2
2018-06-05 14:05