Skip to content

Commit

Permalink
options parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
singalen committed Jul 6, 2017
0 parents commit 463347b
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.idea
/cmake-build-debug
/cmake-build-release
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.8)
project(logrotee)

set(CMAKE_CXX_STANDARD 17)

set(SOURCE_FILES logrotee.cpp)
add_executable(logrotee ${SOURCE_FILES})
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.
113 changes: 113 additions & 0 deletions logrotee.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include <iostream>
#include <string>
#include <getopt.h>

#pragma ide diagnostic ignored "ClangTidyInspection"

using std::string;

const char *programName = "0.1";
const char *programVersion = "0.1";


struct Arguments {
bool invalid;
string logFilePath;
string compressCommand;
string compressSuffix;
bool nullStdout;
size_t chunkSize;
bool dates;
ssize_t maxFiles;

bool isInvalid() const {
return invalid || logFilePath.empty();
}
} commandArgs;

void usage() {
std::cout << "Example usage: verbosecommand | logrotee /var/log/verbosecommand.log"
" --compress \"bzip2 {}\" --compress-suffix .bz2"
" --null --chunk 2M" << std::endl;
}


int main(int argc, char *argv[])
{
int getoptResult;

for(;;) {
int optionIndex = 0;
static struct option longOptions[] = {
{"compress", required_argument, nullptr, 'c' },
{"compress-suffix", required_argument, nullptr, 's' },
{"null", no_argument, nullptr, 'n' },
{"dates", no_argument, nullptr, 'd' },
{"max-files", required_argument, nullptr, 'm'},
{"help", no_argument, nullptr, 'h' },
{"version", no_argument, nullptr, 'v' },
{nullptr, 0, nullptr, 0 }
};

getoptResult = getopt_long(argc, argv, "", longOptions, &optionIndex);
if (getoptResult == -1)
break;

switch (getoptResult) {
case 'c':
commandArgs.compressCommand = optarg;
break;

case 's':
commandArgs.compressSuffix = optarg;
break;

case 'n':
commandArgs.nullStdout = true;
break;

case 'd':
commandArgs.dates = true;
break;

case 'm':
try {
commandArgs.maxFiles = std::stoi(optarg);
}
catch (const std::logic_error& e) {
std::cout << "Cannot parse number: " << optarg << std::endl;
exit(1);
}
break;

case 'h':
usage();
exit(0);

case 'v':
std::cout << programName << " " << programVersion << std::endl;
exit(0);

default:
printf("?? getopt returned character code 0%o ??\n", getoptResult);
}
}

if (optind < argc) {
commandArgs.logFilePath = argv[optind];
optind++;
while (optind < argc) {
commandArgs.invalid = true;
std::cerr << "Extra command line argument:" << argv[optind] << std::endl;
}
}

if (commandArgs.isInvalid()) {
usage();
exit(1);
}



return 0;
}
34 changes: 34 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
What is it?
===========

A kind of `tee` that writes stdin to a rotated log file(s).

EXAMPLES
========

verbosecommand | logrotee /var/log/verbosecommand.log \
> /dev/null
or

verbosecommand | logrotee /var/log/verbosecommand.log \
--compress "bzip2 {}" --compress-suffix .bz2 \
--null --chunk 2M

If the output chunk file + <suffix> already exists, add an unique sequential suffix, currently `.1`, `.2`, `.3`, you get the idea.

USAGE
=====
`logrotee <name> [-z|--compress <compress-command>] [-s|--compress-suffix <suffix>] [-n|--null] [--chunk|-k <size>]`

`<name>`: Chunk file name. If the file exists, will be appended a number, like: `/var/log/verbosecommand.log.1`, `/var/log/verbosecommand.log.2`, and so on.
If `--compress-suffix "bz2"` is given, will check for `/var/log/verbosecommand.log.bz2`, `/var/log/verbosecommand.log.1.bz2` and so on.

`-z`, `--compress` `<compress-command>` Optional parameter - command to run on a complete chunk file. {} is substituted with a full file path.
`-s`, `--compress-suffix` `<suffix>` File suffix to append to check for <name> existence, if
`-n`, `--null` Don't print the file to stdout.

Planned:
=======
`-d`, `--dates` Use dates instead of sequential numbers for rotation suffix.
`-m`, `--max-files` `<amount>` Maximum amount of rotated files. Delete the oldest chunk files when over this limit.
Does not check if the files were not created by this instance of `logrotee`.

0 comments on commit 463347b

Please sign in to comment.