[syslog-ng]Syslog.conf translator

Jon Marks j-marks@uiuc.edu
Wed, 2 May 2001 15:01:26 -0500


--a8Wt8u1KmwUX3Y2C
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Great! I hope it's useful for people. I've made a few changes that
might make it a little better. I've cleaned it up a bit, making it
work more intuitively (I've only just picked up awk). It also now does
the translation in the same order as the statements in syslog.conf,
outputting a commented out version of the translated line before each
translation. I fixed an inaccuracy in the translation which would have
occurred if the same output destination is used twice in syslog.conf. I
added log-device sensitivity for Linux. And finally, I added some comments
to make it easier to understand.


On Wed, May 02, 2001 at 11:47:49AM +0200, Balazs Scheidler wrote:
> On Tue, May 01, 2001 at 06:01:41PM -0500, Jon Marks wrote:
> > Hi,
> > 
> > In order to make the transition to syslog-ng easier for people, I thought
> > it might be useful to have an automated translation from the old
> > syslog.conf to a working syslog-ng.conf. I came up with an awk script
> > which works OK for me. I was targeting Solaris and AIX specifically, but
> > off-hand, RedHat linux syslogd looks the same and I presume other UNIX
> > variants' do, too. Try it, it could work ;)
> > 

> 
> I'd add this script to the contrib subdirectory if you don't mind.
> 
> -- 
> Bazsi
> PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1
> 
> _______________________________________________
> syslog-ng maillist  -  syslog-ng@lists.balabit.hu
> https://lists.balabit.hu/mailman/listinfo/syslog-ng

-- 
Jonathan Marks

Systems Administrator, Production Systems Group
Computing and Communication Services Office
University of Illinois at Urbana-Champaign



--a8Wt8u1KmwUX3Y2C
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=syslog2ng

#!/bin/ksh
#
# syslog2ng
# 
# Translator from syslog.conf to syslog-ng.conf
# by Jonathan W. Marks <j-marks@uiuc.edu>
#
# Rev 2

awk '
BEGIN {
	# Handle the various platforms- determine proper log device
	"/bin/uname -s" | getline sysname;
	close("/bin/uname -s");
	if (sysname == "SunOS") {
		LOGDEVTYPE="sun-streams";
	} else if (sysname == "AIX") {
		LOGDEVTYPE="unix-dgram";
	} else if (sysname == "Linux") {
		LOGDEVTYPE="unix-stream";
	} else {
		print "!!! Unsupported system: " sysname ".";
		exit 1;
	}

	# Output the basic options and source statement.
	print \
"options { dir_perm(0755); perm(0644); chain_hostnames(no);\n" \
"          keep_hostname(yes); };\n";

	print \
"source local {\n" \
"	" LOGDEVTYPE "(\"/dev/log\");\n" \
"	udp(ip(0.0.0.0) port(514));\n" \
"	internal();\n" \
"};\n";
}

$1 !~ /^[:space:]*#/ && NF == 2 { 

	# Output a comment with the line being translated.
	print "# " $0 "\n";

	# Output any new filters to be created, saving filter ID numbers
	# needed by destination
	requiredFilterNos = make_filters($1);

	# Output the destination to be used, saving destination ID number
	destNo = make_destination($2)

	# Output the log path, connecting the required filters to the
	# destination.
	make_log(destNo, requiredFilterNos);
}

function make_filters(filterstr, filterNumbers) {

	# Split the components of the filter specifier. For each component,
	# generate the appropriate filter, and collect the filter numbers.

	split(filterstr, termlist, ";");
	for (termNo in termlist) {
		newNum = make_filter(termlist[termNo]);
		filterNumbers = filterNumbers " " newNum;
	}
	return filterNumbers;
}

function make_filter(spec, negate) {

	# Find the severity and facility list.
	dot = index(spec, ".");
	severity = substr(spec, (dot + 1));
	split(substr(spec, 1, (dot - 1)), faclist, ",");

	if (severity == "none") { negate = 1 };
	if (severity == "*")    { severity = "debug" };

	# Create an ID string using severity and facility list to hash
	# into all_filters. Then we can tell whether weve already built
	# a filter like this.
	filterID = severity;
	for (facno in faclist) {
		filterID = filterID " " faclist[facno];
	}

	# If this is a new filter, output the syslog-ng directives for it
	# and save its ID and number in all_filters.
	if (! (filterID in all_filters)) {
		all_filters[filterID] = ++filterNum;

		printf "filter f_" filterNum " {\n\t";
		nPrinted = 0;

		# If using all facilities, no need to include them all in
		# filter-- its really only a filter based on severity
		if (faclist[1] != "*") {
			printf("%sfacility(", (negate ? "not " : ""));
			for (facno in faclist) {
				printf("%s" faclist[facno], \
					(nPrinted++ > 0 ? "," : ""));
			}
			printf(")%s", (severity != "none" ? " and " : ""));
		}
		if (severity != "none") {
			printf("level(" severity "%s)",
				(severity == "emerg" ? "" : "...emerg"));
		}
		printf(";\n};\n\n");
	}

	return all_filters[filterID];
}

function make_destination(d, destNo) {

	# If weve already built this destination, dont do it again. 
	# Just return the ID number.
	if (d in destinations) {
		return destinations[d];
	}

	# Remember the destination ID number in case we need it again.
	destNo = ++dno;
	destinations[d] = destNo;

	# Output the syslog-ng directive for the destination.
	printf "destination d_" destNo " { \n";
	if (d ~ /^\//) {
		printf "\tfile(\"" d "\" create_dirs(yes));\n";
	}
	else if (d ~ /^@/) {
		printf "\tudp(\"" substr(d, 2) "\" port(514));\n";
	}
	else {
		printf "\tusertty(\"" d "\");\n";
	}		

	print "};\n";
	return destNo;
}

function make_log(destNo, filterNos) {

	# Note the destination number and filter numbers, then output
	# a syslog-ng directive connecting them.	
	n_entries = split(filterNos, filters, " ");
	printf "log { source(local); " ;
	for (i = 1; i <= n_entries; i++) {
		printf "filter(f_" filters[i] "); ";
	}
	print "destination(d_" destNo "); };\n";
}'


--a8Wt8u1KmwUX3Y2C--