This is my first python script ever
I wanted to get a graphical view of the source of the web traffic of my server, and to try python.
First, I created the input file. Its format is
number_of_queries IP
number_of_queries IP
so:
cat access.log | cut -d" " -f 1 | sort | uniq -c | sort > file.txt
Then, I needed a blank world map. Its higher its resolution, the better. This was my biggest problem, with a lot of maps I was getting IPs geolocated to the middle of the ocean. Or mapping Madrid in France. After trying maps for a while, I found
this one.I also needed a geoip database.
wget -q http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz -O - | gunzip > /usr/share/GeoIP/GeoIPCountry.dat
This is the code:
#!/usr/bin/python2
import sys
import cairo
import GeoIP
import math
def draw_circle (cr, center, size):
cr.arc (center[0], center[1], size, 0, math.pi * 2)
cr.fill ()
def draw_line (cr, p_from, p_to):
cr.move_to (p_from[0], p_from[1])
cr.line_to (p_to[0], p_to[1])
cr.stroke ()
def fix_coord (point, zero):
x = zero[0] * point[0] / 180;
y = -zero[1] * point[1] / 90;
return (zero[0] + x, zero[1] + y);
if (len (sys.argv) < 2):
exit ()
my_ip = "208.89.214.47"
gip = GeoIP.open ("/usr/share/GeoIP/GeoIPCountry.dat", GeoIP.GEOIP_STANDARD)
info = gip.record_by_addr (my_ip)
my_coords = [info['longitude'], info['latitude']]
f = open (sys.argv[1])
l = f.readlines ()
f.close ()
total = 0.0
ips = []
for line in l:
ip = line.strip ().split (" ")
info = gip.record_by_addr (ip[1])
ip.append (info)
ips.append (ip)
total += float(ip[0])
src = cairo.ImageSurface.create_from_png ("./map.png")
(width, height) = (src.get_width (), src.get_height ())
zero = [width / 2, height / 2]
cr = cairo.Context (src)
cr.set_antialias (cairo.ANTIALIAS_GRAY)
cr.set_source (cairo.SolidPattern (0, 0, 0, 0.5))
cr.set_line_width (0.1)
arc_min = width / 1000
for ip in ips:
try:
size = float(ip[0])/total
draw_line (cr,
fix_coord (my_coords, zero),
fix_coord ([ip[2]['longitude'], ip[2]['latitude']], zero))
center = fix_coord ([ip[2]['longitude'], ip[2]['latitude']], zero)
draw_circle (cr, center, arc_min + size*10)
except:
pass
src.write_to_png ("traffic.png")
And this is the result.