There is this amazing tool Logstalgia which visualizes web-server logs. Sadly, there were no new builds for Windows after the version 1.0.9, so I decided to make one with the latest version (1.1.2 at the moment).

Logstalgia, Windows build

I will describe the process and also publish pre-built binaries.

About

Logstalgia is really amazing. What it does is it parses the access logs from NGINX, Apache or other web-server and visualizes all the requests and responses sent. It is a such a simple idea, but it serves the purpose so well.

For example, here’s how a DDoS attack on VideoLAN server looked like:

And here’s a visualization of silly attempts to guess the CMS on our server:

If video doesn’t play in your browser, you can download it here.

Mainly I use it to run a live visualization of our website’s access log. Even though it requires SSH, that still can be done on Windows thanks to sh.exe environment from the Git package:

ssh some-host tail -f /var/log/nginx/access.log | /d/programs/logstalgia/logstalgia.exe -b 101010 --font-size 16 -x

When I want to record a video, I run the following:

ssh some-host tail -f /var/log/nginx/access.log | /d/programs/logstalgia/logstalgia.exe -1920x1080 -b 101010 --font-size 16 -x -r 60 -o /d/temp/recording.ppm

And then using FFmpeg:

ffmpeg -r 60 -i recording.ppm -crf 18 -pix_fmt yuv420p output.mp4

Build

Here’s what it takes to build Logstalgia on Windows.

Environment

What I used:

  • Windows 8.1 or 10 (tested on both)
  • CMake
  • Visual Studio Code
  • MSVC 2019 x64
  • MinGW 7.3.0 x64

MSVC 2019 comes as a part of Visual Studio 2019. And MiGW 7.3.0 can be installed from the Qt online installer:

Qt installer, MinGW 7.3.0

Sources

The source code can be cloned from the Logstalgia repository:

git clone --recurse-submodules git@github.com:acaudwell/Logstalgia.git

However, on Windows they recommend to use Qt Creator and qmake. That didn’t work for me, so I went with CMake and Visual Studio Code instead.

And since I plan to publish Windows builds, I needed a place for uploading those, so I forked the Logstalgia repository - and that’s the only purpose of my repository as it is highly unlikely that I will modify anything in the original source code.

Dependencies

Logstalgia depends on quite a few libraries, and that is why building it for Windows is rather an annoying task. Some of those can be found as pre-built binaries, but others I had to build from sources - luckily all of them are built with CMake as well.

Here’re the relevant parts from CMakeLists.txt:

project("logstalgia" VERSION 1.1.2)

set("tools-path" "d:/programs")

# actually, C++11 should be enough
set(CMAKE_CXX_STANDARD 17)

find_package(OpenGL REQUIRED)

# NO_DEFAULT_PATH is set so it wouldn't pick up libraries from other places in PATH
find_library(SDL2 SDL2 PATHS "${tools-path}/sdl/lib/x64" NO_DEFAULT_PATH)
find_library(SDL2main SDL2main PATHS "${tools-path}/sdl/lib/x64" NO_DEFAULT_PATH)
find_library(SDL2_image SDL2_image PATHS "${tools-path}/sdl/sdl-image/lib/x64" NO_DEFAULT_PATH)
find_library(freetype freetype PATHS "${tools-path}/freetype/win64" NO_DEFAULT_PATH)
find_library(libpng libpng16 PATHS "${tools-path}/libpng/lib" NO_DEFAULT_PATH)
find_library(GLEW glew32 PATHS "${tools-path}/glew/lib/Release/x64" NO_DEFAULT_PATH)
find_library(PCRE pcre PATHS "${tools-path}/pcre/lib" NO_DEFAULT_PATH)

include_directories(
    "${tools-path}/boost"
    "${tools-path}/glm/include"
    "${tools-path}/glew/include"
    "${tools-path}/sdl/include"
    "${tools-path}/sdl/sdl-image/include"
    "${tools-path}/freetype/include"
    "${tools-path}/libpng/include"
    "${tools-path}/pcre/include"
    )

# ...

target_link_libraries(${CMAKE_PROJECT_NAME}
    ${OPENGL_gl_LIBRARY}
    ${GLEW}
    ${SDL2}
    ${SDL2main}
    ${SDL2_image}
    ${freetype}
    ${libpng}
    ${PCRE}
    -lglu32
    -static-libgcc
    -static-libstdc++
    -lcomdlg32
    )

Now let’s see how to get all those dependencies.

SDL

Download pre-built package. Development libraries for Visual C++ 32/64-bit.

SDL_image

Download pre-built package. Development libraries for Visual C++ 32/64-bit.

GLEW

Download pre-built package.

freetype

Download pre-built package.

zlib

This one is actually a dependency of libpng. Download the sources and set the install prefix:

project(zlib C)
set (CMAKE_INSTALL_PREFIX "d:/programs/zlib")

Building from Visual Studio Code:

CMake: Configure
CMake: Build
CMake: Install

libpng

Download the sources, set the install prefix and the path to zlib:

project(libpng C ASM)
set (CMAKE_INSTALL_PREFIX "d:/programs/libpng")

# ...

set (ZLIB_ROOT "d:/programs/zlib")

# Allow users to specify location of Zlib.
# Useful if zlib is being built alongside this as a sub-project.
option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF)

Building from Visual Studio Code:

CMake: Configure
CMake: Build
CMake: Install

glm

Download the sources and set the install prefix:

set (CMAKE_INSTALL_PREFIX "d:/programs/glm")

Building from Visual Studio Code:

CMake: Configure
CMake: Build
CMake: Install

boost

Download the library.

PCRE

I don’t know where I was supposed to get PCRE from, because all the pre-built distributions I found did not work for me. So eventually I just built if from source.

There are two versions of PCRE at the moment:

  1. PCRE 8.43 and that’s the one required;
  2. PCRE2 10.33.

So download sources for the first one and build it. It is important to use MinGW x64 kit (the same kit that will be used for building the Logstalgia itself):

VS Code, CMake kit

What I find peculiar though is that I built all the other dependencies using MSVC kit, and that caused no troubles, but when I tried to build PCRE with MSVC, Logstalgia failed to build, so apparently MinGW is a strict requirement here. It is also required to use the Ninja generator.

So, set the install prefix:

set (CMAKE_INSTALL_PREFIX "d:/programs/pcre")

and build it from Visual Studio Code:

CMake: Configure
CMake: Build
CMake: Install

Icon

Let’s also add an application icon. Create resources.rc resource file:

IDI_ICON1 ICON DISCARDABLE "logstalgia.ico"

And add it to CMakeLists.txt:

add_executable(${CMAKE_PROJECT_NAME} ${sources} resources.rc)

Building

Like I said, the original repository suggests to use logstalgia.pro file, which is a qmake project file, and to build it from Qt Creator with MinGW x64.

Nevertheless, in addition to switching to CMake, I tried to build it with MSVC first (and PCRE library build with MSVC), but that failed with the following error:

Cannot open include file: 'unistd.h'

And when I chose MinGW x64 kit with Ninja generator, the project built with no problems.

Well, actually there was one:

undefined reference to '__imp_pcre_compile'
undefined reference to '__imp_pcre_free'
undefined reference to '__imp_pcre_exec'
undefined reference to '__imp_pcre_exec'

I’ve spent quite some time googling the solution, till I found one. From the official example:

/*
If you want to statically link this program against a non-dll .a file, you must
define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and
pcre_free() exported functions will be declared __declspec(dllimport), with
unwanted results. So in this environment, uncomment the following line.
*/

/* #define PCRE_STATIC */

#include <stdio.h>
#include <string.h>
#include <pcre.h>

So I edited the src\core\regex.h:

#define PCRE_STATIC
#include "pcre.h"

Deployment

CMake install

Some silly attempts to make installation instructions for the CMake: Install command:

set(CMAKE_INSTALL_PREFIX "${tools-path}/${CMAKE_PROJECT_NAME}")

# ...

install(TARGETS ${CMAKE_PROJECT_NAME}
    RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
    ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}"
    LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}"
    )
install(DIRECTORY "data" DESTINATION "${CMAKE_INSTALL_PREFIX}")

That will put the logstalgia.exe and its assets from data folder to the installation path, but sadly it will not copy the libraries it depends on, so that needs to be done manually.

DLLs

According to the list of dependencies or through the way of trial and error, here’s a list of .dll’s required for our application to launch:

  • freetype.dll
  • glew32.dll
  • libpng16.dll
  • SDL2.dll
  • SDL2_image.dll
  • zlib.dll

You can also use Dependency Walker to list all the dependencies:

Dependency Walker, Logstalgia

Copy the libraries that are really required to the same folder with logstalgia.exe and here we go:

d:\programs\logstalgia>logstalgia.exe --help
Logstalgia v1.1.2

Hallelujah.

I published the 1.1.2 release here.