logswan

Fast Web log analyzer using probabilistic data structures
Log | Files | Refs | README | LICENSE

commit 83583c21298045128469981e291a342ef5729252
Author: Frederic Cambus <fcambus@users.sourceforge.net>
Date:   Sun,  7 Jun 2015 16:55:30 +0200

Initial commit

Diffstat:
ALICENSE | 28++++++++++++++++++++++++++++
ATODO | 5+++++
Alogswan.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, Frederic Cambus +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Logswan nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/TODO b/TODO @@ -0,0 +1,5 @@ +- Add a Makefile +- Check strtol return value +- Use a struct to store results +- Use strnum on platforms supporting it? (OpenBSD, FreeBSD) +- Use strtok_r instead of strtok to tokenize lines? diff --git a/logswan.c b/logswan.c @@ -0,0 +1,124 @@ +/*****************************************************************************/ +/* */ +/* Logswan (c) by Frederic Cambus 2015 */ +/* https://github.com/fcambus/logswan */ +/* */ +/* Created: 2015/05/31 */ +/* Last Updated: 2015/06/07 */ +/* */ +/* Logswan is released under the BSD 3-Clause license. */ +/* See LICENSE file for details. */ +/* */ +/*****************************************************************************/ + +#include <arpa/inet.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define LINE_MAX_LENGTH 4096 + +clock_t begin, end; +double runtime; + +char lineBuffer[LINE_MAX_LENGTH]; + +uint64_t objectSize = 0; +uint64_t bandwidth = 0; +uint64_t hits = 0; + +struct sockaddr_in ipv4; +struct sockaddr_in6 ipv6; + +struct stat logFileSize; +FILE *logFile; + +char *endptr; + +int main (int argc, char *argv[]) { + printf("-------------------------------------------------------------------------------\n" \ + " Logswan (c) by Frederic Cambus 2015 \n" \ + "-------------------------------------------------------------------------------\n\n"); + + if (argc != 2) { + printf("ERROR : No input file specified."); + return EXIT_FAILURE; + } + + // Starting timer + begin = clock(); + + // Get log file size + stat(argv[1], &logFileSize); + + printf("Processing file : %s\n\n", argv[1]); + + logFile = fopen(argv[1], "r"); + + while (fgets(lineBuffer, LINE_MAX_LENGTH, logFile) != NULL) { + // Tokenize line + + // Remote host + char* token = strtok(lineBuffer, " "); + + if (inet_pton(AF_INET, token, &(ipv4.sin_addr))) { + // Valid IPv4 address + } + + if (inet_pton(AF_INET6, token, &(ipv6.sin6_addr))) { + // Valid IPv6 address + } + + // User-identifier + token = strtok(NULL, " "); + + // User ID + token = strtok(NULL, " "); + + // Date + token = strtok(NULL, " ["); + + // UTC time offset + token = strtok(NULL, " ]"); + + // Method + token = strtok(NULL, " \""); + + // Requested resource + token = strtok(NULL, " "); + + // Protocol + token = strtok(NULL, " \""); + + // HTTP status codes + token = strtok(NULL, " "); + + // Returned object size + token = strtok(NULL, " "); + + // Increment bandwidth usage + if (token) { // Do not feed NULL tokens to strtol + objectSize = strtol(token, &endptr, 10); + bandwidth += objectSize; + } + + // Increment hits counter + hits++; + } + + // Stopping timer + end = clock(); + runtime = (double)(end - begin) / CLOCKS_PER_SEC; + + // Printing results + printf("Hits : %llu\n", hits); + printf("Bandwidth : %llu\n", bandwidth); + printf("Log file size : %llu\n", logFileSize.st_size); + printf("Runtime : %f\n", runtime); + + fclose(logFile); + + return EXIT_SUCCESS; +}