#!/usr/bin/python # encoding: utf-8 import GeoIP import re import sys from collections import Counter from datetime import datetime from log_parsers import ApacheLogParser then = datetime.now() hits_per_remote_addr = Counter() # IP-d kust tuldi hits_per_path = Counter() # URL-id mida külastati hits_per_user_agent = Counter() # User agent mida kasutati külastamisel hits_per_country = Counter() # Riigid kust päringud tulid hits_per_date = Counter() # Kuupäevad mil logikirjeid oli bytes_per_date = Counter() gi = GeoIP.open("/usr/share/GeoIP/GeoIP.dat", GeoIP.GEOIP_MEMORY_CACHE) print "Loen standardsisendist..." for timestamp, log_entry, stack_trace, byte_count, line_count, event_count in ApacheLogParser(sys.stdin): country_code = gi.country_code_by_addr(log_entry.get("remote_addr")) if not country_code: # Jäta vahele sisevõrgu aadressid, localhost jms mis ei lahendu riigiks continue if int(log_entry.get("status")) < 400: # 2xx ja 3xx arvestamiseks hits_per_path[log_entry.get("path")] += 1 hits_per_remote_addr[log_entry.get("remote_addr")] += 1 if "bot" not in log_entry.get("user_agent").lower(): hits_per_user_agent[log_entry.get("user_agent")] += 1 hits_per_country[country_code] += 1 hits_per_date[timestamp.date()] += 1 bytes_per_date[timestamp.date()] += int(log_entry.get("size")) # Leia kõige esimene kuupäev ning viimane kuupäev millal sündmused esinesid first_date, last_date = min(hits_per_date.keys()), max(hits_per_date.keys()) ############################ ### Värvi riigid kaardil ### ############################ import requests from lxml import etree from numpy import interp # Laadi alla kaart wikimedia veebist print "Laadin alla kaarti..." buf = requests.get("https://upload.wikimedia.org/wikipedia/commons/0/03/BlankMap-World6.svg").content # Parsi XML puu map_document = etree.fromstring(buf) # Iga riigikoodi ja sellest riigist pärit päringute arvu kohta for country, count in hits_per_country.items(): if not country: # Mõni IP ei pruukinud laheneda riigikoodiks (sisevõrk jms) continue # Interpoleeri päringute arv vahemikust 0 ... maksimaalsete päringutega riik # vahemikku 180 (sinakas toon) ... 0 (punane) # võrdväärne rida: hue = 180 - 180 * count / max(hits_per_country.values()) hue = interp(count, [0, max(hits_per_country.values())], [180, 0]) # Nopi rekursiivselt dokumendist välja kõik elemendid mille 'id' attribuut on riigikoodiga # Kaardis vastab sellele küll ainult üks ehk grupi element for element in map_document.xpath("//*[@id='%s']" % country.lower()): # Lisa CSS-i stiili attribuut elemendile taustavärvi muutmiseks element.set("style", "fill:hsl(%.2f, 60%%, 60%%)" % hue) # Polügonid mis on grupi sees, neilt eemalda attribuut 'class' mille # abil pannakse vaikimisi hall värv külge for subelement in element: subelement.attrib.pop("class", "") with open("top.svg", "wb") as fh: fh.write(etree.tostring(map_document)) print "Kaart salvestatud faili top.svg" #################################################### ### Koosta päringute arvu graafik päevade lõikes ### #################################################### # matplotlibi serveris kasutamiseks tuleb välja vahetada vaikimisi joonsitamise backend # https://matplotlib.org/tutorials/introductory/usage.html#what-is-a-backend import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 7)) # Lisa joonise sisse kaks graafikut sub = fig.add_subplot(2, 1, 1) sub2 = fig.add_subplot(2, 1, 2) sub.set_xlabel(u"Päringute arv") sub2.set_xlabel(u"Liikluse maht baitides") # Ploti andmepunktid sub.barh(hits_per_date.keys(), hits_per_date.values()) sub2.barh(bytes_per_date.keys(), bytes_per_date.values()) # Salvesta faili fig.savefig("bar.svg", format="svg") fig.savefig("bar.png") ####################################### ### Koosta veebilehitsejate graafik ### ####################################### import pygal line_chart = pygal.Pie( truncate_legend=50, # legend kuni 50 karakterit width=1000, height=300, # graafiku laius/kõrgus pikslites style=pygal.style.Style(background='transparent')) # eemalda taustavärv line_chart.config(style_name = 'LightStyle', fill=None) line_chart.title = 'Veebilehitsejate osakaal' for user_agent, count in hits_per_user_agent.most_common(7): line_chart.add(user_agent, count) # lisa graafikule hits_per_user_agent.pop(user_agent) # eemalda counteri objektist line_chart.add("Muud veebilehitsejad", sum(hits_per_user_agent.values())) user_agent_chart = line_chart.render(is_unicode=True, disable_xml_declaration=True) from jinja2 import Template import codecs # Loe jinja mall UTF-8 tekstifailist with codecs.open("template.html", "rb", encoding="utf-8") as fh: template = Template(fh.read()) # Süsti malli sisse kõik kohalikud muutujad (first_date, last_date, hits, urls jne) buf = template.render(locals()) # Salvesta täidetud leht UTF-8 kodeeringus with codecs.open("raport.html", "wb", encoding="utf-8") as fh: fh.write(buf) print "HTML kujul raport savlestatud faili raport.html"