A simple view/visitor counter for a website in order to provide extremely fast and basic analytics.
Go to file
Steven Polley bb4112e145
All checks were successful
continuous-integration/drone/push Build is passing
initialize database if table doesn't exist
2024-01-01 10:39:16 -07:00
countersql initialize database if table doesn't exist 2024-01-01 10:39:16 -07:00
.drone.yml initial commit 2020-06-03 20:40:13 -06:00
Dockerfile add maintainer to Dockerfile 2020-10-04 21:08:59 +00:00
go.mod update go module 2023-06-10 12:28:00 -06:00
go.sum update go module 2023-06-10 12:28:00 -06:00
main.go initialize database if table doesn't exist 2024-01-01 10:39:16 -07:00
README.md Include requirements and how to build application 2020-06-20 20:55:48 -06:00

siteviewcounter

Build Status

A simple view counter for a website

Requirements

  • Go
  • Docker
  • Docker Compose (Optional) or Kubernetes (Optional)

Build Application


go build -a -ldflags '-w'

Build Container

Disclaimer! If you use this, you'll need to build the container yourself. I have a CICD pipeline setup, but my registry is used for my internal infrastructure only and is not publicly available.

Because this is a staticly linked binary with no external runtime dependancies, the container literally only contains the binary file, keeping it clean and low in size (6.3MB). I never did understand why people include operating systems in containers.


docker build -t siteviewconter:latest .

Example docker-compose.yml

Create a docker-compose file


version: '3.7'

services:
 
  counter:
    image: siteviewcounter:latest
    restart: always
    expose:
      - "8080"
    environment:
      - dbname=counter
      - dbhostname=counter-db
      - dbusername=root
      - dbpassword=CHANGEME
      - timezone=America/Edmonton
      
      
  counter-db:
    image: mariadb:10
    restart: always
    expose:
      - "3306"
    volumes:
      - /data/counter-db:/var/lib/mysql
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_DATABASE=counter
      - TZ=America/Edmonton

Database initialization

The following SQL will initialize the database for this application. No automigrate / initialization is done upon first running the application, so this must be ran by an administrator.

SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;

CREATE DATABASE `counter` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `counter`;

CREATE TABLE `visit` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip_address` varchar(15) NOT NULL,
  `visits` int(11) NOT NULL,
  `last_visited` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Example front end usage

You can pretty much implement this in your front end however you want, you just need to make a GET request to whatever endpoint the counter container is running at. This is how I use it though...

<html>
  <head>
    <script>
      var counterReq = new XMLHttpRequest();
      counterReq.onreadystatechange = function() {
        console.log("counterReq ready state is " + this.readyState);
        if (this.readyState == 4) {
          console.log("counterReq status is " + this.status);
          if (this.status == 200) {
            document.getElementById("counter").innerHTML = this.responseText + " unique visitors"
          } else { // failed to load
            console.log("failed to load counter module")
          }
        }
      }
      counterReq.open("GET", "https://counter.example.com", true);
      counterReq.send();
    </script>
  </head>
  <body>
    <div id="counter"></div>
  </body>
</html>