Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[Pyhton] script genereert inconsistente "count" output.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een pyhton script geschreven welke pattern matching uitvoert over een serie statische maillogs (exim4).
Deze haalt een string op welke een maildomein is. (hotmail.com, yahoo.com, msn.com, etc etc).
Deze strings worden in een dictionary gezet en er word een count gedaan (defaultdict). De hoogste getallen bovenaan.

De functie word aangeroepen door onderstaande code:
if __name__ == '__main__':
domainCounter = DomainCounter()
result = domainCounter.parse_log_files()
domainCounts = defaultdict(int)
top = 3
for domain in result:
    domainCounts[domain] += 1

sortedDict = dict(sorted(domainCounts.items(), key=lambda x: x[1], reverse=True)[:int(top)])
for w in sorted(sortedDict, key=sortedDict.get, reverse=True):
    print '%-3s %s' % (sortedDict[w], w)


Hieronder de output van het script die 3x achter elkaar is uitgevoerd:
1:
7035 gmail.com
6833 hotmail.com
5365 yahoo.com
2:
7002 gmail.com
6774 hotmail.com
5439 yahoo.com
3:
7019 gmail.com
6791 hotmail.com
5443 yahoo.com

Ik vermoed dat de data inconsistent is omdat ik een dubbele sort gebruik.
Echter heb ik niet voldoende kennis om deze eruit te slopen zonder mijn hele script te slopen.

Hulp word op prijs gesteld.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:08
Dat twee keer sorteren verklaart niet waarom de aantallen niet kloppen. Ik denk dat er voor het sorteren al iets fout gaat. (Wat is overigens het nut van twee keer sorteren? De eerste sortering is toch al precies wat je wil?)

  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

Is de output van domainCounter.parse_log_files() stabiel, als in, altijd hetzelfde?

Is deze vraag ook van jou? Je gebruikt hier os.popen, maar blocked niet op het resultaat. Het unzippen, of in dit geval bzippen, is nog bezig. Ondertussen lees je al wel de file. os.popen is trouwens deprecated sinds python 2.6. Ik heb het ook even daar gezet in mijn steenkolen-Engels. :)

[ Voor 6% gewijzigd door Feanathiel op 12-03-2014 19:58 ]


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Kan je het niet even natellen? :+

Of een andere taal ter controle gebruiken:
C#:
1
2
3
List<string> domains = new List<string> { "x", "y", "z", "w", "x", "y", "z", "x", "x", "z" };
foreach (var g in (from d in domains group d by d into g orderby g.Count() descending select g).Take(3))
    Console.WriteLine("{0}: {1}", g.Count(), g.Key);


geeft:
4: x
3: z
2: y

[ Voor 13% gewijzigd door Daos op 12-03-2014 20:59 . Reden: code mooier ]


  • DXaroth
  • Registratie: Maart 2011
  • Laatst online: 24-08 19:58
Ik zou adviseren om een kleine dataset te gebruiken, en ondertussen wat debugging toevoegen om te zien wat er gebeurt...

Dubbel sorteren heeft weinig nut, maar zou niet de waardes op enige manier aanpassen.

Verwijderd

Topicstarter
Feanathiel schreef op woensdag 12 maart 2014 @ 19:53:
Is de output van domainCounter.parse_log_files() stabiel, als in, altijd hetzelfde?

Is deze vraag ook van jou? Je gebruikt hier os.popen, maar blocked niet op het resultaat. Het unzippen, of in dit geval bzippen, is nog bezig. Ondertussen lees je al wel de file. os.popen is trouwens deprecated sinds python 2.6. Ik heb het ook even daar gezet in mijn steenkolen-Engels. :)
Goed gezien, die vraag is inderdaad van mij. O-)
Edit: Je opmerking over de popen functie: Lijkt een logische reden dat de count niet consistent is.
Ik zal dit implimenteren in mijn script en kijken of het resultaat oplevert.

[ Voor 11% gewijzigd door Verwijderd op 13-03-2014 10:16 ]


Verwijderd

Topicstarter
Ik heb wat onderzoek gedaan hoe ik dit het beste kon tackelen, en kwam uit op de python subprocess lib.
De "proccessFiles" methode heb ik met deze lib aangepast, maar ik doe waarschijlijk iets verkeer in de syntax.

Bij het aftrappen van het script rapporteerd bunzip deze fouten:
"Proccessing /opt/syslog/app/applog-20140314.bz2. bunzip2: Can't open input file > : No such file or directory. bunzip2: Compressed file ends unexpectedly; perhaps it is corrupted? *Possible reason follows. bunzip2: No such file or directory Input file = /var/tmp/parsed_applog-20140314.decompressed, output file = (stdout)" 


code:
1
2
3
4
5
6
7
8
9
10
11
12
def parse_log_files(self):
    sub_dir = os.listdir(self.base_path)
    for directory in sub_dir:
        if re.search('app\d+', directory):
            fileInput = self.base_path + '/' + directory + '/applog-' + str(self.date.strftime('%Y%m%d')) + '.bz2'
            fileDest = '/var/tmp/parsed_log_files-'  + str(self.date.strftime('%Y%m%d')) + '.decompressed'
            if not os.path.isfile(fileDest):
                subprocess.Popen(['touch',fileDest]).communicate()[0]
            proccessFiles = subprocess.Popen(['/bin/bunzip2','-cd',fileInput,' > ',fileDest],stdout=subprocess.PIPE).communicate()[0]
            accessFileHandle =  open(self.file_out, 'r')
            readFileHandle = accessFileHandle.readlines()
            print "Proccessing %s." % fileInput

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:08
Ja, > is de shell redirection operator; niet een bestandsnaam. Vandaar dat bzip2 klaagt: "can't open input file >".

Wat wil je nu trouwens? De uitvoer naar fileDest schrijven of via een pipe (stdout=subprocess.PIPE) in Python inlezen? In het laatste geval kun je gewoon bzcat <filename> doen (wat neerkomt op bunzip2 -cd <filename>.

Verwijderd

Topicstarter
Cheers, totaal gemist dat ">" het probleem is, wat duidelijk te zien is in de error...

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Misschien de bzip2 library van python zelf gebruiken?

http://docs.python.org/2/library/bz2.html
Pagina: 1