Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 4, 2021 07:54 pm GMT

Build a web traffic monitor with Django and IPStack

In today's online world, it is important to know where your website traffic comes from in order to help website owners understand their visitors better. In this tutorial, we build a very basic traffic monitor, the traffic monitor will display details about visitors on the website. For every visitor, there will multiple columns such as time of visit, continent, country and city.

Getting started with IPStack API

IPStack offers a powerful, real-time IP to geolocation API capable of looking up accurate location data and assessing security threats originating from risky IP addresses. Results are delivered within milliseconds in JSON or XML format. Using the ipstack API you will be able to locate website visitors at first glance and adjust your user experience and application accordingly.

The documentation outlines in detail the API features, available options and integration guides in different programming languages.

Get a free API access key to proceed using this API.

Sample API Response

IPStack API responses come with comprehensive location-related data, currency-related data, timezone-related data, connection-related data and security-related data. Have a look at the example below.

Please note: For illustration purposes we have included both Hostname Lookup and the Security Module in the above API response. Please refer to the sections Hostname Lookup and Security Module for details.

{  "ip": "134.201.250.155",  "hostname": "134.201.250.155",  "type": "ipv4",  "continent_code": "NA",  "continent_name": "North America",  "country_code": "US",  "country_name": "United States",  "region_code": "CA",  "region_name": "California",  "city": "Los Angeles",  "zip": "90013",  "latitude": 34.0453,  "longitude": -118.2413,  "location": {    "geoname_id": 5368361,    "capital": "Washington D.C.",    "languages": [        {          "code": "en",          "name": "English",          "native": "English"        }    ],    "country_flag": "https://assets.ipstack.com/images/assets/flags_svg/us.svg",    "country_flag_emoji": "",    "country_flag_emoji_unicode": "U+1F1FA U+1F1F8",    "calling_code": "1",    "is_eu": false  },  "time_zone": {    "id": "America/Los_Angeles",    "current_time": "2018-03-29T07:35:08-07:00",    "gmt_offset": -25200,    "code": "PDT",    "is_daylight_saving": true  },  "currency": {    "code": "USD",    "name": "US Dollar",    "plural": "US dollars",    "symbol": "$",    "symbol_native": "$"  },  "connection": {    "asn": 25876,    "isp": "Los Angeles Department of Water & Power"  },  "security": {    "is_proxy": false,    "proxy_type": null,    "is_crawler": false,    "crawler_name": null,    "crawler_type": null,    "is_tor": false,    "threat_level": "low",    "threat_types": null  }}

Prerequisites

Following Python best practices, we will create a virtual environment for our project, and install the required packages.

First, create the project directory.

$ mkdir djangoapp$ cd djangoapp

Now, create a virtual environment and install the required packages.

For macOS and Unix systems:

$ python3 -m venv myenv$ source myenv/bin/activate(myenv) $ pip install django requests cloudinary

For Windows:

$ python3 -m venv myenv$ myenv\Scripts\activate(myenv) $ pip install django requests

Setting Up Your Django Application

First, navigate to the directory djangoapp we created and establish a Django project.

(myenv) $ django-admin startproject mainapp

This will auto-generate some files for your project skeleton:

mainapp/    manage.py    mainapp/        __init__.py        settings.py        urls.py        asgi.py        wsgi.py

Now, navigate to the directory you just created (make sure you are in the same directory as manage.py) and create your app directory.

(myenv) $ python manage.py startapp monitor

This will create the following:

monitor/    __init__.py    admin.py    apps.py    migrations/        __init__.py    models.py    tests.py    views.py

On the mainapp/settings.py file, look for the following line and add the app we just created above.

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'monitor', #new line]

Ensure you are in the monitor directory then create a new directory called templates and a new file called urls.py. Your directory structure of monitor application should look like this

monitor/    __init__.py    admin.py    apps.py    migrations/    templates/        __init__.py    models.py    tests.py    urls.py    views.py

Ensure your mainapp/urls.py file, add our monitor app URL to include the URLs we shall create next on the monitor app:

from django.contrib import adminfrom django.urls import path, includeurlpatterns = [    #path('admin/', admin.site.urls),    path('', include('monitor.urls')),#monitor app url]

Now, on the monitor/urls.py file, add our website there:

from django.urls import path, includefrom . import viewsurlpatterns = [    path('', views.home, name="home"),    path('monitor/', views.monitor, name="monitor"), #system monitor view to be created next]

Create our database models which we shall use to store our website visitors information. On the monitor/models.py file:

from django.db import models# Create your models here.class Monitor(models.Model):    continent = models.CharField(max_length=50, blank=True, null=True)    country = models.CharField(max_length=50, blank=True, null=True)    city = models.CharField(max_length=50, blank=True, null=True)    capital = models.CharField(max_length=50, blank=True, null=True)    datetime = models.DateField(max_length=50, blank=True, null=True)    ip = models.CharField(max_length=50, blank=True, null=True)    def __str__(self):        return self.ip

Now, on the monitor/views.py file, add the lines below:

from django.shortcuts import render, redirectimport requestsimport timeimport psutilimport osfrom datetime import datetimefrom .models import Monitorfrom urllib.parse import urlparseimport cloudinary.uploaderfrom django.core.paginator import Paginator#traffic monitordef traffic_monitor(request):    dataSaved = Monitor.objects.all().order_by('-datetime')    # Getting loadover15 minutes     load1, load5, load15 = psutil.getloadavg()    cpu_usage = int((load15/os.cpu_count()) * 100)    ram_usage = int(psutil.virtual_memory()[2])    p = Paginator(dataSaved, 100)    #shows number of items in page    totalSiteVisits = (p.count)    #find unique page viewers & Duration    pageNum = request.GET.get('page', 1)    page1 = p.page(pageNum)    #unique page viewers    a = Monitor.objects.order_by().values('ip').distinct()    pp = Paginator(a, 10)    #shows number of items in page    unique = (pp.count)    #update time    now = datetime.now()    data = {        "now":now,        "unique":unique,        "totalSiteVisits":totalSiteVisits,        "cpu_usage": cpu_usage,        "ram_usage": ram_usage,        "dataSaved": page1,    }    return render(request, 'traffic_monitor.html', data)#home pagedef home(request):    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')    if x_forwarded_for:        ip = x_forwarded_for.split(',')[0]    else:        ip = request.META.get('REMOTE_ADDR')    response = requests.get('http://api.ipstack.com/'+ip+'?access_key=GETYOURACCESSKEY') #change from HTTP to HTTPS on the IPSTACK API if you have a premium account    rawData = response.json()    print(rawData) # print this out to look at the response    continent = rawData['continent_name']    country = rawData['country_name']    capital = rawData['city']    city = rawData['location']['capital']    now = datetime.now()    datetimenow = now.strftime("%Y-%m-%d %H:%M:%S")    saveNow = Monitor(        continent=continent,        country=country,        capital=capital,        city=city,        datetime=datetimenow,        ip=ip    )    saveNow.save()    return render(request, 'home.html')

In the code above on the home view, the code starts by getting the users IP address. On getting the visitors IP, we then make a request to IPStack with the IP address above appended to the request and store the results to the database. If you wish to collect more information, just add them on the models and add the variable like so above with the respective data you are collecting eg country.

For the traffic monitor view, the code starts buy getting all data on the Monitor table and renders the data on the HTML page which we shall create below. The code also collects the cpu and ram usage of the system. Let us now proceed to rendering the data above on our webpage.

On the monitor/templates folder, create traffic_monitor.html and home.html web page and add the lines below:

monitor/templates/traffic_monitor.html file:

<!doctype html><html lang="en">  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">    <meta name="description" content="">    <meta name="author" content="">    <title>ALienx &#8211; Connections</title>    <link rel="canonical" href="https://getbootstrap.com/docs/4.0/examples/album/">    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">    <!-- Bootstrap core CSS -->    <link href="https://getbootstrap.com/docs/4.0/dist/css/bootstrap.min.css" rel="stylesheet">    <!-- Custom styles for this template -->    <link href="https://getbootstrap.com/docs/4.0/examples/album/album.css" rel="stylesheet">  </head>  <body>    <header>      <div class="collapse bg-dark" id="navbarHeader">        <div class="container">          <div class="row">            <div class="col-sm-8 col-md-7 py-4">              <h4 class="text-white">About</h4>              <p class="text-muted">Add some information about the album below, the author, or any other background context. Make it a few sentences long so folks can pick up some informative tidbits. Then, link them off to some social networking sites or contact information.</p>            </div>            <div class="col-sm-4 offset-md-1 py-4">              <h4 class="text-white">Contact</h4>              <ul class="list-unstyled">                <li><a href="#" class="text-white">Follow on Twitter</a></li>                <li><a href="#" class="text-white">Like on Facebook</a></li>                <li><a href="#" class="text-white">Email me</a></li>              </ul>            </div>          </div>        </div>      </div>      <div class="navbar">        <div class="container d-flex justify-content-between">          <a href="#" class="navbar-brand d-flex align-items-center">            <i class="fa fa-desktop" aria-hidden="true"></i> <strong> Site Visitors</strong>          </a>          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">            <span class="navbar-toggler-icon"></span>          </button>        </div>      </div>    </header>    <main role="main">      <section class="jumbotron text-center">        <div class="container">          <h1 class="jumbotron-heading"><i class="fa fa-desktop" aria-hidden="true"></i> Site Visitors and Resources Monitor</h1>          <p class="lead text-muted">Contact <a href="#">developer</a> if CPU & RAM USAGE exceeds 80%</p>        </div>      </section>      <div class="album py-7 bg-light">            <div class="content-wrapper">                <div class="container-fluid">                  <ol class="breadcrumb">                    <li class="breadcrumb-item">                      <a href="#">Dashboard</a>                    </li>                    <li class="breadcrumb-item active">Site Traffic & Resources Monitor</li>                  </ol>                  <br>                  <!-- Icon Cards-->                  <div class="container">                    <div class="row">                        <div class="col-sm-3 block">                            <div class="circle a">                                <p><b>CPU Usage</b>                                    <br>                                    <b>{{ cpu_usage }}%</b>                                </p>                            </div>                        </div>                        <div class="col-sm-3 block">                            <div class="circle b">                                <p><b>RAM Usage</b>                                     <br>                                    <b>{{ ram_usage }}%</b>                                </p>                            </div>                        </div>                        <div class="col-sm-3 block">                            <div class="circle c">                                <p><b>Total Site Visits</b>                                     <br>                                    {{ totalSiteVisits }}                                </p>                            </div>                        </div>                        <div class="col-sm-3 block">                            <div class="circle d">                                <p><b>Unique Page Views</b>                                    <br>                                    {{ unique }}                                </p>                            </div>                        </div>                    </div>                </div>                <style>                  .block {                                    bottom: 30px;    text-align: center;    vertical-align: middle;}.circle {    font-size: 15px;    background: white;    border-radius: 200px;    color: white;    height: 170px;    font-weight: bolder;    width: 170px;    display: table;    margin: 20px auto;}.circle p {    vertical-align: middle;    display: table-cell;}                    .a {                        background-color: #39c0dc;                    }                    .b {                        background-color: darkorange;                    }                    .c {                        background-color: #5c6dfd;                    }                    .d {                        background-color: #f14c6e;                    }                    .g {                        background-color: greenyellow;                    }                    .f{                        background-color: fuchsia;                    }                </style>                  <!-- Example contextTables Card-->                  <div class="card mb-3">                    <div class="card-header">                      <b style="color: #0664c9;"><i class="fa fa-table"></i> User Sessions</b></div>                    <div class="card-body">                      <div class="table-responsive">                        <table class="table table-bordered" id="contextTable" width="100%" cellspacing="0">                          <thead>                            <tr>                              <th>Time</th>                              <th>IP Address</th>                              <th>Continent</th>                              <th>Country</th>                              <th>City</th>                            </tr>                          </thead>                          <tfoot>                            <tr>                              <th>Time</th>                              <th>IP Address</th>                              <th>Continent</th>                              <th>Country</th>                              <th>City</th>                            </tr>                          </tfoot>                          <tbody id="customer-table">                            {% for data in dataSaved.object_list %}                            <tr>                                <td>{{ data.datetime }}</td>                                            <td>{{ data.ip }}</td>                                <td>{{ data.continent }}</td>                                <td>{{ data.country }}</td>                                <td>{{ data.city }}</td>                            </tr>                            {% endfor %}                          </tbody>                        </table>                      </div>                      <br>                      <nav aria-label="...">                        {% if dataSaved.has_other_pages %}                        <ul class="pagination justify-content-center">                            {% if dataSaved.has_previous %}                          <li class="page-item">                            <a class="page-link" href="?page={{ dataSaved.previous_page_number }}" tabindex="-1">Previous</a>                          </li>                          {% endif %}                          {% for i in dataSaved.paginator.page_range %}                             {% if dataSaved.number == i %}                          <li class="page-item active">                              <a class="page-link" href="#">{{ i }}<span class="sr-only">(current)</span></a>                           </li>                          {% endif %}                          {% endfor %}                           <li class="page-item">                            {% if dataSaved.has_next %}                            <a class="page-link" href="?page={{ dataSaved.next_page_number }}">Next</a>                            {% endif %}                          </li>                        </ul>                        {% endif %}                    </nav>                    </div>                    <div class="card-footer small text-muted">Updated at <span id="session-update-time">{{ now }}</span></div>                  </div>                </div>      </div>    </main>    <footer class="text-muted">      <div class="container">        <p class="float-right">          <a href="#">Back to top</a>        </p>        <p>Need help? <a href="#">Contact site developer</a> or the <a href="#">site admin</a>.</p>      </div>    </footer>    <!-- Bootstrap core JavaScript    ================================================== -->    <!-- Placed at the end of the document so the pages load faster -->    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>    <script src="https://getbootstrap.com/docs/4.0/assets/js/vendor/popper.min.js"></script>    <script src="https://getbootstrap.com/docs/4.0/dist/js/bootstrap.min.js"></script>    <script src="https://getbootstrap.com/docs/4.0/assets/js/vendor/holder.min.js"></script>  </body></html>

On the monitor/templates/home.html file:

<!doctype html><html lang="en">  <head>    <!-- Required meta tags -->    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- Bootstrap CSS -->    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">    <title>Hello, world!</title>  </head>  <body>    <h1>Hello, world!</h1>    <!-- Optional JavaScript; choose one of the two! -->    <!-- Option 1: Bootstrap Bundle with Popper -->    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>    <!-- Option 2: Separate Popper and Bootstrap JS -->    <!--    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>    -->  </body></html>

Testing if it Works!

Migrate, then run the server by running the commands below then navigating to the respective port:

(myenv) $ python manage.py makemigrations(myenv) $ python manage.py migrate(myenv) $ python manage.py runserver

Below is a snapshot of my implementation:

save.jpg

Thanks for reading!

I hope you enjoyed this blog as much as i did, incase of any question, feel free to ask on the comment section below. Note, you can play with this data as you like, like adding a date range filter to show visitors by date or showing the visitors by country.


Original Link: https://dev.to/paulwababu/build-a-web-traffic-monitor-with-django-and-ipstack-3n2g

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To