Compare commits

...

18 commits
10.0.0 ... main

Author SHA1 Message Date
847f4ab742
Fix report CPU_TYPE in hardware.sh for RPIs
Changes:

* For CPU_TYPE in hardware.sh, report something if /proc/cpuinfo does not
  contain processor model information
2025-02-19 11:35:40 -05:00
17d6163514
Merge in Splunk Add-On for Unix and Linux version 10.0.0 2025-02-05 17:18:14 -05:00
ce9dada330
Fix alignment and fix packages for Arch Linux
Changes:

* Align columns with "column -t"
* Add Arch Linux support in packages.sh
2025-02-03 18:08:38 -05:00
f3e4386480
Add Version to update.sh for Darwin
Changes:

* Add version to update.sh for Darwin
2025-01-25 15:30:25 -05:00
653ee79a67
Fix Darwin Scripts and Document Sudo
Changes:

* Use sudo in service.sh for Darwin to find user services if not running as root
* Fix parsing the output of softwareupdate command on Darwin in update.sh
* Better document usage of sudo in docs/Sudo.md
2025-01-25 15:11:30 -05:00
a24e4c8ee5
Fix OpenBSD Support and Other Bugs
Changes:

* Fix OpenBSD cpu.sh output to match others
* Fix OpenBSD df.sh output (no need for %% here)
* Do not use sudo or doas when running as root
* Use #!/usr/bin/env bash to support OpenBSD in run_nix_ta_commands
* Fix rsyslog example to trim whitespace in run_nix_ta_commands
* Add /usr/local/sbin:/usr/local/bin to PATH in run_nix_ta_commands
* Fix getting hour and minute for OpenBSD in run_nix_ta_commands
  "08" shows up to printf as octal
* Support difference in OpenBSD logger command:
  Requires modifying /etc/syslog.conf and setting facility in /etc/nix_ta.conf
2025-01-25 13:41:20 -05:00
8c02cbc5cc
Support OpenBSD
Add OpenBSD support to the scripts
Fix sysctl usage for FreeBSD in a couple places
2025-01-25 02:07:17 -05:00
24f6e18ef8
Fix df.sh and df_metric.sh
Fix Linux when df outputs a "-"
Exclude efivars partitions for Linux
Fix the output on Darwin to match Linux output
2025-01-23 18:19:40 -05:00
718a9f787c
Fix run_nix_ta_commands script
* Make run_nix_ta_commands (in extra) use /etc/nix_ta.conf for its settings
  instead of hard-coding them in the script
2025-01-20 15:59:46 -05:00
e5e03ea464
Fix docker script and props
* Fix output for docker script (handle lines that didn't have values)
* Fix props.conf LINE_BREAKER for docker
2025-01-17 11:44:24 -05:00
5551b8973d
Add script for docker events/metrics and support running TA outside of Splunk
* Add docker.sh and docker_metric.sh for collecting docker events/metrics
* Add helper script to extra/ to run the TA commands on systems without
  a Splunk forwarder. The commands can be sent to a syslog server.
  This script is useful for systems with small or read-only filesystems that
  cannot support a Universal Forwarder.
* Add syslog_inputs_nix_ta app to extra/ for ingesting the data from syslog
2025-01-11 23:28:44 -05:00
5e766d84d5
Make distro_name work everywhere
* For MacOS, print MacOS for distro_name
* For others, print $KERNEL for distro_name
2025-01-11 15:07:24 -05:00
cb7f7785c8
Fix bug in 9.2.0.2
* Add code I forgot for machine_arch for Linux
* Add Makefile to make making releases easier
2025-01-11 14:45:28 -05:00
53e0e8b8f0
improve Makefile 2025-01-11 14:27:35 -05:00
b4d814d90d
add Makefile for building releases 2025-01-11 14:22:51 -05:00
c2893d577b
Improvements for version.sh 2025-01-11 14:02:23 -05:00
7b0b703510
Fix other Splunk Add-on references
Replace all references to Splunk Add-on with Technical Add-on
Replace URLs
Remove splunkbase stuff
Add copyright
2025-01-09 17:55:11 -05:00
07122cafad
Use ip command to determine IP address ('hostname -I' does not work on all Linux systems)
Filter out multiple listing of the same btrfs volume
Use mktemp for temp files (for times when the TA may be run outside of Splunk)
If running rlog.sh outside of Splunk, use $HOME to store seek file
Debian also uses apt
Arch Linux uses pacman
Add use of sudo -n for 'apt update' and 'pacman -Syy'
vmstat uses "K paged out"
Replace the use of 'sar' with netstat and vm_stat for MacOS
2025-01-08 18:21:51 -05:00
54 changed files with 1569 additions and 871 deletions

23
Makefile Normal file
View file

@ -0,0 +1,23 @@
TEMP_DIR := $(shell mktemp -d)
WORK_DIR := $(TEMP_DIR)/TA-unix
VERSION := $(shell head -n1 VERSION)
TAR_FILE := ./ta-for-unix-and-linux-$(VERSION).tgz
all: release
updateversion:
ifndef NEW
$(error NEW is not specified. Usage make NEW=<newversion> updateversion)
endif
sed -ri "s/$(VERSION)/$(NEW)/g" app.manifest default/app.conf VERSION
release:
mkdir -p $(WORK_DIR)
cp -R . $(WORK_DIR)/
rm -Rf $(WORK_DIR)/Makefile $(WORK_DIR)/.git $(WORK_DIR)/local $(WORK_DIR)/bin/__pycache__ $(WORK_DIR)/ta-for-unix-and-linux-*.tgz
tar -C $(TEMP_DIR) -czf $(TAR_FILE) TA-unix
test -d $(HOME)/Downloads && cp $(TAR_FILE) $(HOME)/Downloads
rm -Rf $(TEMP_DIR)
clean:
rm -Rf ./ta-for-unix-and-linux-*.tgz $(TEMP_DIR)

View file

@ -1,4 +1,8 @@
Splunk Add-on for Unix and Linux
Technical Add-on for Unix and Linux
Copyright (C) 2025 Michael Erdely All Rights Reserved.
Copyright (C) 2024 Splunk Inc. All Rights Reserved.
For documentation, see: https://docs.splunk.com/Documentation/AddOns/released/UnixLinux/
For documentation, see: https://git.erdelynet.com/mike/TA-unix/src/branch/main/docs/ReleaseNotes.md
For documentation on Splunk's Add-on for Unix and Linux (which applies to this TA too), see:
https://docs.splunk.com/Documentation/AddOns/released/UnixLinux/

View file

@ -7,9 +7,9 @@
The following 3rd-party software packages may be used by or distributed with splunk-add-on-for-unix-and-linux. Any information relevant to third-party vendors listed below are collected using common, reasonable means.
Date generated: 2024-7-5
Date generated: 2025-1-31
Revision ID: a08b431842df3cfc234ba3f0675de8898f9ef6ac
Revision ID: 79a4b3bf642285d427e11cd81adb8baaf923e0e9
================================================================================
================================================================================
@ -55,7 +55,14 @@ No licenses found
================================================================================
================================================================================
Copyrights
================================================================================
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Report Generated by FOSSA on 2024-7-5
Report Generated by FOSSA on 2025-1-31

View file

@ -1,2 +1,2 @@
9.2.0
9.2.0
10.0.0.1
10.0.0.1

View file

@ -1,66 +1,66 @@
{
"dependencies": null,
"incompatibleApps": null,
"info": {
"author": [
{
"company": "Splunk, Inc.",
"email": "support@splunk.com",
"name": "Splunk, Inc."
}
],
"classification": {
"categories": [
"IT Operations",
"Utilities"
],
"developmentStatus": "Production/Stable",
"intendedAudience": "IT"
},
"commonInformationModels": {
"Authentication": "=4.20.2",
"Change": "=4.20.2",
"Endpoint": "=4.20.2",
"Inventory": "=4.20.2",
"Network Sessions": "=4.20.2",
"Performance": "=4.20.2"
},
"description": "Splunk Add-on for Unix and Linux",
"id": {
"group": null,
"name": "Splunk_TA_nix",
"version": "9.2.0"
},
"license": {
"name": "Splunk Software License Agreement",
"text": "LICENSES/LicenseRef-Splunk-8-2021.txt",
"uri": "http://www.splunk.com/view/SP-CAAAAFA"
},
"privacyPolicy": {
"name": null,
"text": null,
"uri": null
},
"releaseDate": null,
"releaseNotes": {
"name": "README",
"text": "./README.txt",
"uri": "https://docs.splunk.com/Documentation/AddOns/released/UnixLinux/Releasenotes"
},
"title": "Splunk Add-on for Unix and Linux"
"dependencies": null,
"incompatibleApps": null,
"info": {
"author": [
{
"name": "Michael Erdely",
"email": mike@erdelynet.com,
"company": "erdelynet.com"
}
],
"classification": {
"categories": [
"IT Operations",
"Utilities"
],
"developmentStatus": "Production/Stable",
"intendedAudience": "IT"
},
"inputGroups": null,
"platformRequirements": null,
"schemaVersion": "2.0.0",
"supportedDeployments": [
"_standalone",
"_distributed",
"_search_head_clustering"
],
"targetWorkloads": [
"_search_heads",
"_forwarders",
"_indexers"
],
"tasks": null
}
"commonInformationModels": {
"Authentication": "==4.20.2",
"Change": "==4.20.2",
"Endpoint": "==4.20.2",
"Inventory": "==4.20.2",
"Network Sessions": "==6.0.2",
"Performance": "==4.20.2"
},
"description": "Technical Add-on for Unix and Linux",
"id": {
"group": null,
"name": "TA-unix",
"version": "10.0.0.1"
},
"license": {
"name": "Splunk Software License Agreement",
"text": "LICENSES/LicenseRef-Splunk-8-2021.txt",
"uri": "http://www.splunk.com/view/SP-CAAAAFA"
},
"privacyPolicy": {
"name": null,
"text": null,
"uri": null
},
"releaseDate": null,
"releaseNotes": {
"name": "README",
"text": "./README.txt",
"uri": "https://git.erdelynet.com/mike/TA-unix/docs/ReleaseNotes.md"
},
"title": "Technical Add-on for Unix and Linux"
},
"inputGroups": null,
"platformRequirements": null,
"schemaVersion": "2.0.0",
"supportedDeployments": [
"_standalone",
"_distributed",
"_search_head_clustering"
],
"targetWorkloads": [
"_search_heads",
"_forwarders",
"_indexers"
],
"tasks": null
}

View file

@ -25,7 +25,7 @@ define([
root.ScriptedInput = root.Entity.extend({
path: function () {
// Approximate path - accepts reads only
// ex: data/inputs/script/%2FApplications%2Fsplunk_622light_unix%2Fetc%2Fapps%2FSplunk_TA_nix%2Fbin%2Fcpu.sh
// ex: data/inputs/script/%2FApplications%2Fsplunk_622light_unix%2Fetc%2Fapps%2FTA-unix%2Fbin%2Fcpu.sh
return Paths.monitorInputs + '/' + encodeURIComponent(this.name)
},

View file

@ -9,8 +9,8 @@ require([
'splunkjs/mvc/simplexml/ready!',
'underscore',
'jquery',
'../app/Splunk_TA_nix/components/js_sdk_extensions/scripted_inputs',
'../app/Splunk_TA_nix/components/js_sdk_extensions/monitor_inputs'
'../app/TA-unix/components/js_sdk_extensions/scripted_inputs',
'../app/TA-unix/components/js_sdk_extensions/monitor_inputs'
], function (mvc, ignored, _, $, sdkx_scripted_inputs, sdkx_monitor_inputs) {
var ScriptedInputs = sdkx_scripted_inputs.ScriptedInputs
var MonitorInputs = sdkx_monitor_inputs.MonitorInputs
@ -66,11 +66,11 @@ require([
var monitorInputs = {}
new MonitorInputs(service, {
owner: '-',
app: 'Splunk_TA_nix',
app: 'TA-unix',
sharing: 'app'
}).fetch(function (err, inputs) {
var inputsList = _.filter(inputs.list(), function (input) {
return input.namespace.app === 'Splunk_TA_nix'
return input.namespace.app === 'TA-unix'
})
_.each(inputsList, function (input) {
@ -93,7 +93,7 @@ require([
var scriptedMetricInputs = {}
new ScriptedInputs(service, {
owner: '-',
app: 'Splunk_TA_nix',
app: 'TA-unix',
sharing: 'app'
}).fetch(function (err, inputs) {
var inputsList = _.filter(inputs.list(), function (input) {
@ -101,7 +101,7 @@ require([
.substring(input.name.lastIndexOf('/') + 1)
.split('_')
return (
input.namespace.app === 'Splunk_TA_nix' &&
input.namespace.app === 'TA-unix' &&
input_name[input_name.length - 1] === 'metric.sh'
)
})
@ -129,7 +129,7 @@ require([
var scriptedEventInputs = {}
new ScriptedInputs(service, {
owner: '-',
app: 'Splunk_TA_nix',
app: 'TA-unix',
sharing: 'app'
}).fetch(function (err, inputs) {
var inputsList = _.filter(inputs.list(), function (input) {
@ -137,7 +137,7 @@ require([
.substring(input.name.lastIndexOf('/') + 1)
.split('_')
return (
input.namespace.app === 'Splunk_TA_nix' &&
input.namespace.app === 'TA-unix' &&
input_name[input_name.length - 1] !== 'metric.sh'
)
})

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -6,6 +7,8 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
HEADER='Name rxPackets_PS txPackets_PS rxKB_PS txKB_PS'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%s %s %s %s %s\n", Name, rxPackets_PS, txPackets_PS, rxKB_PS, txKB_PS}'
@ -66,11 +69,11 @@ elif [ "$KERNEL" = "AIX" ] ; then
# shellcheck disable=SC2016
FORMAT='{Name=$1; rxPackets_PS=$5; txPackets_PS=$7; rxKB_PS="?"; txKB_PS="?"}'
elif [ "$KERNEL" = "Darwin" ] ; then
CMD='sar -n DEV 1 2'
CMD='eval ifconfig -a -u | awk "/^[^ \t]/{i=substr(\$1,1,length(\$1)-1)}/status: active/{print i}" | while read -r int; do netstat -bnI $int -w 1 | head -n3 | sed "s/^/$int/"; done'
# shellcheck disable=SC2016
FILTER='($0 !~ "Average" || $0 ~ "sar" || $2~/lo[0-9]|IFACE/) {next}'
FILTER='$2~/^(input|packets)$/{next}'
# shellcheck disable=SC2016
FORMAT='{Name=$2; rxPackets_PS=$3; txPackets_PS=$5; rxKB_PS=$4/1024; txKB_PS=$6/1024}'
FORMAT='{Name=$1; rxPackets_PS=$2; txPackets_PS=$5; rxKB_PS=$4/1024; txKB_PS=$7/1024}'
elif [ "$KERNEL" = "HP-UX" ] ; then
# Sample output: http://h20565.www2.hp.com/hpsc/doc/public/display?docId=emr_na-c02263324
CMD='netstat -i 1 2'
@ -78,6 +81,10 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
FILTER='($0 ~ "Name|sar| lo") {next}'
# shellcheck disable=SC2016
FORMAT='{Name=$1; rxPackets_PS=$5; txPackets_PS=$7; rxKB_PS=?; txKB_PS=?}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD='eval ifconfig -a | awk "/UP/ && /RUNNING/ && \$1 != \"lo0:\" {print substr(\$1, 1, length(\$1) - 1)}" | while read -r int; do echo $int $(netstat -bnI $int -w 1 | head -n4 | tail -n1) $(netstat -nI $int -w 1 | head -n 4 | tail -n1 ); done'
# shellcheck disable=SC2016
FORMAT='{Name=$1; rxPackets_PS=$6; txPackets_PS=$8; rxKB_PS=$2/1024; txKB_PS=$2/1024}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
CMD='sar -n DEV 1 2'
# shellcheck disable=SC2016
@ -87,6 +94,6 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
fi
assertHaveCommand "$CMD"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$HEADERIZE $FILTER $FORMAT $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"
# jscpd:ignore-end

View file

@ -71,6 +71,9 @@ case "x$KERNEL" in
;;
"xFreeBSD")
;;
"xOpenBSD")
AWK=gawk
;;
"xAIX")
;;
"xHP-UX")

View file

@ -5,9 +5,11 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
HEADER='CPU pctUser pctNice pctSystem pctIowait pctIdle'
assertHaveCommand column
HEADER='Datetime CPU pctUser pctNice pctSystem pctIowait pctIdle'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-3s %9s %9s %9s %9s %9s\n", cpu, pctUser, pctNice, pctSystem, pctIowait, pctIdle}'
PRINTF='{printf "%-28s %-3s %9s %9s %9s %9s %9s\n", datetime, cpu, pctUser, pctNice, pctSystem, pctIowait, pctIdle}'
if [ "$KERNEL" = "Linux" ] ; then
queryHaveCommand sar
@ -15,19 +17,32 @@ if [ "$KERNEL" = "Linux" ] ; then
queryHaveCommand mpstat
FOUND_MPSTAT=$?
if [ $FOUND_SAR -eq 0 ] ; then
CMD='sar -P ALL 1 1'
CMD='sar -P ALL 2 5'
# shellcheck disable=SC2016
FORMAT='{cpu=$(NF-6); pctUser=$(NF-5); pctNice=$(NF-4); pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$NF}'
FORMAT='{datetime = strftime("%m/%d/%y_%H:%M:%S_%Z"); cpu=$(NF-6); pctUser=$(NF-5); pctNice=$(NF-4); pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$NF}'
elif [ $FOUND_MPSTAT -eq 0 ] ; then
CMD='mpstat -P ALL 1 1'
CMD='mpstat -P ALL 2 5'
# shellcheck disable=SC2016
FORMAT='{cpu=$(NFIELDS-10); pctUser=$(NFIELDS-9); pctNice=$(NFIELDS-8); pctSystem=$(NFIELDS-7); pctIowait=$(NFIELDS-6); pctIdle=$NF}'
FORMAT='{datetime = strftime("%m/%d/%y_%H:%M:%S_%Z"); cpu=$(NFIELDS-10); pctUser=$(NFIELDS-9); pctNice=$(NFIELDS-8); pctSystem=$(NFIELDS-7); pctIowait=$(NFIELDS-6); pctIdle=$NF}'
else
failLackMultipleCommands sar mpstat
fi
# shellcheck disable=SC2016
FILTER='($0 ~ /CPU/) { if($(NF-1) ~ /gnice/){ NFIELDS=NF; } else {NFIELDS=NF+1;} next} /Average|Linux|^$|%/ {next}'
PRINTF='{
if ($0 ~ /all/) {
print header;
printf "%-28s %-3s %9s %9s %9s %9s %9s\n", datetime, cpu, pctUser, pctNice, pctSystem, pctIowait, pctIdle;
} else {
printf "%-28s %-3s %9s %9s %9s %9s %9s\n", datetime, cpu, pctUser, pctNice, pctSystem, pctIowait, pctIdle;
}
}'
$CMD | tee "$TEE_DEST" | $AWK "$FILTER $FORMAT $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$FILTER $FORMAT $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"
exit
elif [ "$KERNEL" = "SunOS" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
if [ "$SOLARIS_8" = "true" ] || [ "$SOLARIS_9" = "true" ] ; then
CMD='eval mpstat -a -p 1 2 | tail -1 | sed "s/^[ ]*0/all/"; mpstat -p 1 2 | tail -r'
else
@ -35,9 +50,9 @@ elif [ "$KERNEL" = "SunOS" ] ; then
fi
assertHaveCommand "$CMD"
# shellcheck disable=SC2016
FILTER='($1=="CPU") {exit 1}'
FILTER='($1=="CPU") {exit 1}'
# shellcheck disable=SC2016
FORMAT='{cpu=$1; pctUser=$(NF-4); pctNice="0"; pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$(NF-1)}'
FORMAT='{datetime="'"$formatted_date"'"; cpu=$1; pctUser=$(NF-4); pctNice="0"; pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$(NF-1)}'
elif [ "$KERNEL" = "AIX" ] ; then
queryHaveCommand mpstat
queryHaveCommand lparstat
@ -76,76 +91,140 @@ elif [ "$KERNEL" = "AIX" ] ; then
DEFINE="-v CPUPool=$CPUPool -v OnlineVirtualCPUs=$OnlineVirtualCPUs -v EntitledCapacity=$EntitledCapacity"
# Get cpu stats using mpstat command and manipulate the output for adding extra fields
CMD='mpstat -a 1 1'
CMD='mpstat -a 2 5'
# shellcheck disable=SC2016
FORMAT='BEGIN {flag = 0}
FORMAT='
function get_current_time() {
# Use "date" to fetch the current time and store it in a variable
command = "date +\"%m/%d/%y_%H:%M:%S_%Z\"";
command | getline datetime;
close(command);
return datetime;
}
BEGIN {
flag = 0;
header = "";
}
{
if($0 ~ /System configuration|^$/) {next}
if($1 ~ /^-+$/ && header != "") {
print header;
next;
}
if($0 ~ /cpu / && flag == 1) {next}
if(flag == 1)
{
# Prepend extra field values from lparstat
for(i=NF+4; i>=4; i--)
for(i=NF+5; i>=5; i--)
{
$i = $(i-3);
$i = $(i-4);
}
if($0 ~ /ALL/)
{
$1 = CPUPool;
$2 = OnlineVirtualCPUs;
$3 = EntitledCapacity;
$1 = get_current_time();
$2 = CPUPool;
$3 = OnlineVirtualCPUs;
$4 = EntitledCapacity;
}
else
{
$1 = "-";
$1 = get_current_time();
$2 = "-";
$3 = "-";
$4 = "-";
}
}
if($0 ~ /cpu /)
{
# Prepend extra field headers from lparstat
for(i=NF+4; i>=4; i--)
for(i=NF+5; i>=5; i--)
{
$i = $(i-3);
$i = $(i-4);
}
$1 = "CPUPool";
$2 = "OnlineVirtualCPUs";
$3 = "EntitledCapacity";
$1 = "Datetime";
$2 = "CPUPool";
$3 = "OnlineVirtualCPUs";
$4 = "EntitledCapacity";
flag = 1;
header = $1;
for (i = 2; i <= NF; i++) {
header = header sprintf("%21s ", $i);
}
}
for(i=1; i<=NF; i++)
printf $1;
for(i=2; i<=NF; i++)
{
printf "%17s ", $i;
printf "%21s ", $i;
}
print "";
}'
fi
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$FORMAT"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$FORMAT" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE '$FORMAT'" >> "$TEE_DEST"
exit
elif [ "$KERNEL" = "Darwin" ] ; then
HEADER='CPU pctUser pctSystem pctIdle'
HEADER='Datetime CPU pctUser pctSystem pctIdle'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-3s %9s %9s %9s \n", cpu, pctUser, pctSystem, pctIdle}'
PRINTF='{printf "%-28s %-3s %9s %9s %9s \n", datetime, cpu, pctUser, pctSystem, pctIdle}'
# top command here is used to get a single instance of cpu metrics
CMD='top -l 1'
CMD='top -l 5 -s 2'
assertHaveCommand "$CMD"
# FILTER here skips all the rows that doesn't match "CPU".
# shellcheck disable=SC2016
FILTER='($1 !~ "CPU") {next;}'
# FORMAT here removes '%'in the end of the metrics.
# shellcheck disable=SC2016
FORMAT='function remove_char(string, char_to_remove) {
sub(char_to_remove, "", string);
return string;
}
{
cpu="all";
pctUser = remove_char($3, "%");
pctSystem = remove_char($5, "%");
pctIdle = remove_char($7, "%");
}'
FORMAT='
function get_current_time() {
# Use "date" to fetch the current time and store it in a variable
command = "date +\"%m/%d/%y_%H:%M:%S_%Z\"";
command | getline datetime;
close(command);
return datetime;
}
function remove_char(string, char_to_remove) {
sub(char_to_remove, "", string);
return string;
}
{
datetime=get_current_time();
cpu="all";
pctUser = remove_char($3, "%");
pctSystem = remove_char($5, "%");
pctIdle = remove_char($7, "%");
}'
PRINTF='{
print header;
printf "%-28s %-3s %9s %9s %9s \n", datetime, cpu, pctUser, pctSystem, pctIdle;
}'
$CMD | tee "$TEE_DEST" | $AWK "$FILTER $FORMAT $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$FILTER $FORMAT $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"
exit
elif [ "$KERNEL" = "OpenBSD" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
CMD='eval top -1 -b; top -b'
assertHaveCommand "$CMD"
# shellcheck disable=SC2016
FILTER='($0 !~ "^([0-9]+[\t ]+)?CPU"){next;}'
# shellcheck disable=SC2016
FORMAT='{
if ($1 ~ /^[0-9]+$/)
cpu="all";
else if ($1 ~ /^CPU[0-9]+$/)
cpu=substr($1,4);
else cpu=0;
datetime="'"$formatted_date"'";
pctUser=substr($3,1,length($3)-1);
pctNice=substr($5,1,length($5)-1);
pctSystem=substr($7,1,length($7)-1);
pctIowait=substr($11,1,length($11)-1);
pctIdle=substr($13,1,length($13)-1);
}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
CMD='eval top -P -d2 c; top -d2 c'
assertHaveCommand "$CMD"
# shellcheck disable=SC2016
@ -155,6 +234,9 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
sub(char_to_remove, "", string);
return string;
}
{
datetime="'"$formatted_date"'";
}
{
if ($1 == "CPU:") {
cpu = "all";
@ -169,16 +251,7 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
pctIdle = remove_char($(NF-1), "%");
pctIowait = "0.0";
}'
elif [ "$KERNEL" = "HP-UX" ] ; then
queryHaveCommand sar
FOUND_SAR=$?
if [ $FOUND_SAR -eq 0 ] ; then
CMD='sar -M 1 1 ALL'
fi
FILTER='/HP-UX|^$|%/ {next}'
# shellcheck disable=SC2016
FORMAT='{k=0; if(5<NF) k=1} {cpu=$(1+k); pctUser=$(2+k); pctNice="0"; pctSystem=$(3+k); pctIowait=$(4+k); pctIdle=$(5+k)}'
fi
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$HEADERIZE $FILTER $FORMAT $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -1,13 +1,16 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
HEADER='CPU pctUser pctNice pctSystem pctIowait pctIdle OSName OS_version IP_address'
assertHaveCommand column
HEADER='Datetime pctUser pctNice pctSystem pctIowait pctIdle OSName OS_version IP_address CPU'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-3s %9s %9s %9s %9s %9s %-35s %15s %-16s\n", cpu, pctUser, pctNice, pctSystem, pctIowait, pctIdle, OSName, OS_version, IP_address}'
PRINTF='{printf "%-28s %9s %9s %9s %9s %9s %-35s %15s %-16s %-3s\n", datetime, pctUser, pctNice, pctSystem, pctIowait, pctIdle, OSName, OS_version, IP_address,cpu}'
FILL_DIMENSIONS='{length(IP_address) || IP_address = "?";length(OS_version) || OS_version = "?";length(OSName) || OSName = "?"}'
if [ "$KERNEL" = "Linux" ] ; then
@ -16,24 +19,25 @@ if [ "$KERNEL" = "Linux" ] ; then
queryHaveCommand mpstat
FOUND_MPSTAT=$?
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
fi
if [ $FOUND_SAR -eq 0 ] ; then
CMD='sar -P ALL 1 1'
CMD='sar -P ALL 2 5'
# shellcheck disable=SC2016
FORMAT='{cpu=$(NF-6); pctUser=$(NF-5); pctNice=$(NF-4); pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$NF;OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
FORMAT='{datetime = strftime("%m/%d/%y_%H:%M:%S_%Z"); cpu=$(NF-6); pctUser=$(NF-5); pctNice=$(NF-4); pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$NF;OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
elif [ $FOUND_MPSTAT -eq 0 ] ; then
CMD='mpstat -P ALL 1 1'
CMD='mpstat -P ALL 2 5'
# shellcheck disable=SC2016
FORMAT='{cpu=$(NFIELDS-10); pctUser=$(NFIELDS-9); pctNice=$(NFIELDS-8); pctSystem=$(NFIELDS-7); pctIowait=$(NFIELDS-6); pctIdle=$NF;OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
FORMAT='{datetime = strftime("%m/%d/%y_%H:%M:%S_%Z"); cpu=$(NFIELDS-10); pctUser=$(NFIELDS-9); pctNice=$(NFIELDS-8); pctSystem=$(NFIELDS-7); pctIowait=$(NFIELDS-6); pctIdle=$NF;OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
else
failLackMultipleCommands sar mpstat
fi
# shellcheck disable=SC2016
FILTER='($0 ~ /CPU/) { if($(NF-1) ~ /gnice/){ NFIELDS=NF; } else {NFIELDS=NF+1;} next} /Average|Linux|^$|%/ {next}'
elif [ "$KERNEL" = "SunOS" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
if [ "$SOLARIS_8" = "true" ] || [ "$SOLARIS_9" = "true" ] ; then
CMD='eval mpstat -a -p 1 2 | tail -1 | sed "s/^[ ]*0/all/"; mpstat -p 1 2 | tail -r'
else
@ -44,7 +48,7 @@ elif [ "$KERNEL" = "SunOS" ] ; then
# shellcheck disable=SC2016
FILTER='($1=="CPU") {exit 1}'
# shellcheck disable=SC2016
FORMAT='{cpu=$1; pctUser=$(NF-4); pctNice="0"; pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$(NF-1);OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
FORMAT='{datetime="'"$formatted_date"'"; cpu=$1; pctUser=$(NF-4); pctNice="0"; pctSystem=$(NF-3); pctIowait=$(NF-2); pctIdle=$(NF-1);OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
elif [ "$KERNEL" = "AIX" ] ; then
queryHaveCommand mpstat
queryHaveCommand lparstat
@ -84,67 +88,81 @@ elif [ "$KERNEL" = "AIX" ] ; then
DEFINE_LPARSTAT_FIELDS="-v CPUPool=$CPUPool -v OnlineVirtualCPUs=$OnlineVirtualCPUs -v EntitledCapacity=$EntitledCapacity"
# Get cpu stats using mpstat command and manipulate the output for adding extra fields
CMD='mpstat -a 1 1'
CMD='mpstat -a 2 5'
# shellcheck disable=SC2016
FORMAT='BEGIN {flag = 0}
FORMAT='
function get_current_time() {
# Use "date" to fetch the current time and store it in a variable
command = "date +\"%m/%d/%y_%H:%M:%S_%Z\"";
command | getline datetime;
close(command);
return datetime;
}
$1 ~ /^-+$/ { next }
BEGIN {flag = 0}
{
if($0 ~ /System configuration|^$/) {next}
if($0 ~ /cpu / && flag == 1) {next}
if(flag == 1)
{
for(i=NF+7; i>=7; i--)
for(i=NF+8; i>=8; i--)
{
$i = $(i-6);
$i = $(i-7);
}
# Prepend OSName, OS_version, IP_address values
$1 = OSName;
$2 = OSVersion/1000;
$3 = IP_address;
# Prepend Datetime, OSName, OS_version, IP_address values
$1 = get_current_time();
$2 = OSName;
$3 = OSVersion/1000;
$4 = IP_address;
# Prepend lparstat field values
if($0 ~ /ALL/)
{
$4 = CPUPool;
$5 = OnlineVirtualCPUs;
$6 = EntitledCapacity;
$5 = CPUPool;
$6 = OnlineVirtualCPUs;
$7 = EntitledCapacity;
}
else
{
$4 = "-";
$5 = "-";
$6 = "-";
$7 = "-";
}
}
if($0 ~ /cpu /)
{
for(i=NF+7; i>=7; i--)
for(i=NF+8; i>=8; i--)
{
$i = $(i-6);
$i = $(i-7);
}
# Prepend OSName, OS_version, IP_address headers
$1 = "OSName";
$2 = "OS_version";
$3 = "IP_address";
# Prepend Datetime, OSName, OS_version, IP_address headers
$1 = "Datetime";
$2 = "OSName";
$3 = "OS_version";
$4 = "IP_address";
# Prepend lparstat field headers
$4 = "CPUPool";
$5 = "OnlineVirtualCPUs";
$6 = "EntitledCapacity";
$5 = "CPUPool";
$6 = "OnlineVirtualCPUs";
$7 = "EntitledCapacity";
flag = 1;
}
for(i=1; i<=NF; i++)
printf $1;
for(i=2; i<=NF; i++)
{
printf "%17s ", $i;
}
print "";
}'
fi
$CMD | tee "$TEE_DEST" | $AWK $DEFINE $DEFINE_LPARSTAT_FIELDS "$FORMAT $FILL_DIMENSIONS"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE $DEFINE_LPARSTAT_FIELDS "$FORMAT $FILL_DIMENSIONS" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE $DEFINE_LPARSTAT_FIELDS '$FORMAT $FILL_DIMENSIONS'" >>"$TEE_DEST"
exit
elif [ "$KERNEL" = "Darwin" ] ; then
HEADER='CPU pctUser pctSystem pctIdle OSName OS_version IP_address'
HEADER='Datetime pctUser pctSystem pctIdle OSName OS_version IP_address CPU'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-3s %9s %9s %9s %-35s %15s %-16s\n", cpu, pctUser, pctSystem, pctIdle, OSName, OS_version, IP_address}'
PRINTF='{printf "%-28s %9s %9s %9s %-35s %15s %-16s %-3s\n", datetime, pctUser, pctSystem, pctIdle, OSName, OS_version, IP_address, cpu}'
# top command here is used to get a single instance of cpu metrics
CMD='top -l 1'
CMD='top -l 5 -s 2'
assertHaveCommand "$CMD"
# FILTER here skips all the rows that doesn't match "CPU".
# shellcheck disable=SC2016
@ -153,20 +171,52 @@ elif [ "$KERNEL" = "Darwin" ] ; then
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1)"
# FORMAT here removes '%'in the end of the metrics.
# shellcheck disable=SC2016
FORMAT='function remove_char(string, char_to_remove) {
sub(char_to_remove, "", string);
return string;
}
{
cpu="all";
pctUser = remove_char($3, "%");
pctSystem = remove_char($5, "%");
pctIdle = remove_char($7, "%");
OSName=OSName;
OS_version=OS_version;
IP_address=IP_address;
}'
FORMAT='
function get_current_time() {
# Use "date" to fetch the current time and store it in a variable
command = "date +\"%m/%d/%y_%H:%M:%S_%Z\"";
command | getline datetime;
close(command);
return datetime;
}
function remove_char(string, char_to_remove) {
sub(char_to_remove, "", string);
return string;
}
{
datetime=get_current_time();
cpu="all";
pctUser = remove_char($3, "%");
pctSystem = remove_char($5, "%");
pctIdle = remove_char($7, "%");
OSName=OSName;
OS_version=OS_version;
IP_address=IP_address;
}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
CMD='eval top -1 -b; top -b'
assertHaveCommand "$CMD"
# shellcheck disable=SC2016
FILTER='($0 !~ "^([0-9]+[\t ]+)?CPU"){next;}'
# shellcheck disable=SC2016
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1)"
# shellcheck disable=SC2016
FORMAT='{
if ($1 ~ /^[0-9]+$/)
cpu="all";
else if ($1 ~ /^CPU[0-9]+$/)
cpu=substr($1,4);
else cpu=0;
datetime="'"$formatted_date"'";
pctUser=substr($3,1,length($3)-1);
pctNice=substr($5,1,length($5)-1);
pctSystem=substr($7,1,length($7)-1);
pctIowait=substr($11,1,length($11)-1);
pctIdle=substr($13,1,length($13)-1);
}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
formatted_date=$(date +"%m/%d/%y_%H:%M:%S_%Z")
CMD='eval top -P -d2 c; top -d2 c'
assertHaveCommand "$CMD"
# shellcheck disable=SC2016
@ -178,6 +228,9 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
sub(char_to_remove, "", string);
return string;
}
{
datetime="'"$formatted_date"'";
}
{
if ($1 == "CPU:") {
cpu = "all";
@ -195,17 +248,7 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
OS_version=OS_version;
IP_address=IP_address;
}'
elif [ "$KERNEL" = "HP-UX" ] ; then
queryHaveCommand sar
FOUND_SAR=$?
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1)"
if [ $FOUND_SAR -eq 0 ] ; then
CMD='sar -M 1 1 ALL'
fi
FILTER='/HP-UX|^$|%/ {next}'
# shellcheck disable=SC2016
FORMAT='{k=0; if(5<NF) k=1} {cpu=$(1+k); pctUser=$(2+k); pctNice="0"; pctSystem=$(3+k); pctIowait=$(4+k); pctIdle=$(5+k); OSName=OSName;OS_version=OS_version;IP_address=IP_address;}'
fi
# shellcheck disable=SC2086
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$HEADERIZE $FILTER $FORMAT $FILL_DIMENSIONS $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$HEADERIZE $FILTER $FORMAT $FILL_DIMENSIONS $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE '$HEADERIZE $FILTER $FORMAT $FILL_DIMENSIONS $PRINTF' header=\"$HEADER\"" >>"$TEE_DEST"

View file

@ -1,10 +1,13 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
# jscpd:ignore-start
if [ "$KERNEL" = "Linux" ] ; then
assertHaveCommand df
@ -12,7 +15,9 @@ if [ "$KERNEL" = "Linux" ] ; then
# shellcheck disable=SC2016
BEGIN='BEGIN { OFS = "\t" }'
# shellcheck disable=SC2016
FILTER_POST='/(devtmpfs|tmpfs)/ {next}'
FILTER_PRE='$2=="btrfs"&&btrfs[$1]==1{next}$2=="btrfs"{btrfs[$1]=1}'
# shellcheck disable=SC2016
FILTER_POST='/(devtmpfs|tmpfs|efivars)/ {next}'
# shellcheck disable=SC2016
PRINTF='
{
@ -214,50 +219,43 @@ elif [ "$KERNEL" = "Darwin" ] ; then
#Maps fsType
# shellcheck disable=SC2016
MAP_FS_TO_TYPE='/ on / {
for(i=1;i<=NF;i++){
if($i=="on" && $(i+1) ~ /^\/.*/)
{
for (i = 1; i <= NF; i++) {
if ($i == "on" && $(i + 1) ~ /^\/.*/)
key=$(i+1);
}
if($i ~ /^\(/)
value=substr($i,2,length($i)-2);
value = substr($i, 2, length($i) - 2);
}
fsTypes[key]=value;
fsTypes[key] = value;
}'
PRINTF='/^Filesystem/ {
printf "Filesystem\tType\tSize\tUsed\tAvail\tUse%%\tInodes\tIUsed\tIFree\tIUse%%\tMountedOn\n";
}
$0 !~ /^Filesystem/ && $0 !~ / on / {
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, fsTypes[$NF], $2, $3, $4, $5, $6+$7, $6, $7, $8, $9;
}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand mount
assertHaveCommand df
CMD='eval mount -t nodevfs,nonfs,noswap,nocd9660; df -ih -t nodevfs,nonfs,noswap,nocd9660'
# shellcheck disable=SC2016
BEGIN='BEGIN { OFS = "\t" }'
#Maps fsType
# shellcheck disable=SC2016
MAP_FS_TO_TYPE='/ on / {
for (i = 1; i <= NF; i++){
if ($i == "on" && $(i + 1) ~ /^\/.*/)
key = $(i + 1);
}
fsTypes[key] = $5;
}'
# Append Type and Inode headers to the main header and print respective fields from values stored in MAP_FS_TO_TYPE variables
# shellcheck disable=SC2016
PRINTF='
{
if($0 ~ /^Filesystem.*/){
sub("%iused","IUsePct",$0);
for(i=1;i<=NF;i++){
if($i=="iused") iusedCol=i;
if($i=="ifree") ifreeCol=i;
if($i=="Mounted" && $(i+1)=="on"){
mountedCol=i;
sub("Mounted on","MountedOn",$0);
}
}
$(NF+1)="Type";
$(NF+1)="INodes";
print $0;
}
PRINTF='/^Filesystem/ {
print "Filesystem\tType\tSize\tUsed\tAvail\tUse%\tInodes\tIUsed\tIFree\tIUse%\tMountedOn";
}
{
for(i=1;i<=NF;i++)
{
if($i ~ /^\/dev\/.*s[0-9]+$/){
sub("^/dev/", "", $i);
sub("s[0-9]+$", "", $i);
}
if($i ~ /^\/\S*/ && i==mountedCol){
$(NF+1)=fsTypes[$mountedCol];
$(NF+1)=$iusedCol+$ifreeCol;
print $0;
}
}
$0 !~ /^Filesystem/ && $0 !~ / on / {
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, fsTypes[$NF], $2, $3, $4, $5, $6+$7, $6, $7, $8, $9;
}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
@ -314,5 +312,5 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
fi
# jscpd:ignore-end
$CMD | tee "$TEE_DEST" | $AWK "$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -1,10 +1,13 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
# shellcheck disable=SC2016
FILL_DIMENSIONS='{length(IP_address) || IP_address = "?";length(OS_version) || OS_version = "?";length(OSName) || OSName = "?";length(IPv6_Address) || IPv6_Address = "?"}'
@ -13,14 +16,16 @@ if [ "$KERNEL" = "Linux" ] ; then
assertHaveCommand df
CMD='df -k --output=source,fstype,size,used,avail,pcent,itotal,iused,iavail,ipcent,target'
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
fi
BEGIN='BEGIN { OFS = "\t" }'
FORMAT='{OSName=OSName;OS_version=OS_version;IP_address=IP_address;IPv6_Address=IPv6_Address}'
# shellcheck disable=SC2016
FILTER_POST='/(devtmpfs|tmpfs)/ {next}'
FILTER_PRE='$2=="btrfs"&&btrfs[$1]==1{next}$2=="btrfs"{btrfs[$1]=1}'
# shellcheck disable=SC2016
FILTER_POST='/(devtmpfs|tmpfs|efivars)/ {next}'
# shellcheck disable=SC2016
PRINTF='
function rem_pcent(val)
@ -29,20 +34,19 @@ if [ "$KERNEL" = "Linux" ] ; then
{val=substr(val, 1, length(val)-1); return val}
}
{
if($0 ~ /^Filesystem.*/){
if ($0 ~ /^Filesystem.*/) {
sub("Mounted on","MountedOn",$0);
$(NF+1)="OSName";
$(NF+1)="OS_version";
$(NF+1)="IP_address";
$(NF+1)="IPv6_Address";
print $0;
} else {
if ($10 == "-") $10 = "0%";
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4, $5, rem_pcent($6), $7, $8, $9, rem_pcent($10), $11, OSName, OS_version, IP_address, IPv6_Address;
}
match($0,/^(.*[^ ]) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+%|-) +(.*)$/,a);
if (length(a) != 0)
{ printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", a[1], a[2], a[3], a[4], a[5], rem_pcent(a[6]), a[7], a[8], a[9], rem_pcent(a[10]), a[11], OSName, OS_version, IP_address, IPv6_Address}
}'
elif [ "$KERNEL" = "SunOS" ] ; then
@ -233,63 +237,47 @@ elif [ "$KERNEL" = "Darwin" ] ; then
#Maps fsType
# shellcheck disable=SC2016
MAP_FS_TO_TYPE='/ on / {
for(i=1;i<=NF;i++){
if($i=="on" && $(i+1) ~ /^\/.*/)
{
for (i = 1; i <= NF; i++) {
if ($i == "on" && $(i + 1) ~ /^\/.*/)
key=$(i+1);
}
if($i ~ /^\(/)
value=substr($i,2,length($i)-2);
value = substr($i, 2, length($i) - 2);
}
fsTypes[key]=value;
fsTypes[key] = value;
}'
# Append Type and Inode headers to the main header and print respective fields from values stored in MAP_FS_TO_TYPE variables
# shellcheck disable=SC2016
PRINTF='
{
if($0 ~ /^Filesystem.*/){
sub("%iused","IUsePct",$0);
for(i=1;i<=NF;i++){
if($i=="iused") iusedCol=i;
if($i=="ifree") ifreeCol=i;
if($i=="Mounted" && $(i+1)=="on"){
mountedCol=i;
sub("Mounted on","MountedOn",$0);
}
}
$(NF+1)="Type";
$(NF+1)="INodes";
$(NF+1)="OSName";
$(NF+1)="OS_version";
$(NF+1)="IP_address";
$(NF+1)="IPv6_Address";
print $0;
}
PRINTF='/^Filesystem/ {
printf "Filesystem\tType\t1K-blocks\tUsed\tAvail\tUse%%\tInodes\tIUsed\tIFree\tIUse%%\tMountedOn\tOSName\tOS_version\tIP_address\tIPv6_Address\n";
}
{
for(i=1;i<=NF;i++)
{
if($i ~ /.*\%$/)
$i=substr($i, 1, length($i)-1);
$0 !~ /^Filesystem/ && $0 !~ / on / {
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, fsTypes[$NF], $2, $3, $4, substr($5, 1, length($5) - 1), $6+$7, $6, $7, substr($8, 1, length($8) - 1), $9, OSName, OS_version, IP_address, IPv6_Address;
}'
if($i ~ /^\/dev\/.*s[0-9]+$/){
sub("^/dev/", "", $i);
sub("s[0-9]+$", "", $i);
}
if($i ~ /^\/\S*/ && i==mountedCol){
$(NF+1)=fsTypes[$mountedCol];
$(NF+1)=$iusedCol+$ifreeCol;
$(NF+1)=OSName;
$(NF+1)=OS_version;
$(NF+1)=IP_address;
$(NF+1)=IPv6_Address;
print $0;
}
elif [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand mount
assertHaveCommand df
CMD='eval mount -t nodevfs,nonfs,noswap,nocd9660; df -ih -t nodevfs,nonfs,noswap,nocd9660'
# Filters have been applied to get rid of IPv6 addresses designated for special usage to extract only the global IPv6 address.
# shellcheck disable=SC2016
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1) -v IPv6_Address=$(ifconfig -a | grep inet6 | grep -v ' ::1 ' | grep -v ' ::1/' | grep -v ' ::1%' | grep -v ' fe80::' | grep -v ' 2002::' | grep -v ' ff00::' | head -n 1 | xargs | cut -d '/' -f 1 | cut -d '%' -f 1 | cut -d ' ' -f 2)"
BEGIN='BEGIN { OFS = "\t" }'
#Maps fsType
# shellcheck disable=SC2016
MAP_FS_TO_TYPE='/ on / {
for (i = 1; i <= NF; i++){
if ($i == "on" && $(i + 1) ~ /^\/.*/)
key = $(i + 1);
}
fsTypes[key] = $5;
}'
# Append Type and Inode headers to the main header and print respective fields from values stored in MAP_FS_TO_TYPE variables
# shellcheck disable=SC2016
PRINTF='/^Filesystem/ {
printf "Filesystem\tType\t1K-blocks\tUsed\tAvail\tUse%%\tInodes\tIUsed\tIFree\tIUse%%\tMountedOn\tOSName\tOS_version\tIP_address\tIPv6_Address\n";
}
$0 !~ /^Filesystem/ && $0 !~ / on / {
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, fsTypes[$NF], $2, $3, $4, substr($5, 1, length($5) - 1), $6+$7, $6, $7, substr($8, 1, length($8) - 1), $9, OSName, OS_version, IP_address, IPv6_Address;
}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
@ -360,5 +348,5 @@ fi
# jscpd:ignore-end
# shellcheck disable=SC2086
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $FILL_DIMENSIONS $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $FILL_DIMENSIONS $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE '$BEGIN $HEADERIZE $FILTER_PRE $MAP_FS_TO_TYPE $FORMAT $FILTER_POST $NORMALIZE $FILL_DIMENSIONS $PRINTF' header=\"$HEADER\"" >>"$TEE_DEST"

116
bin/docker.sh Executable file
View file

@ -0,0 +1,116 @@
#!/bin/bash
# SPDX-FileCopyrightText: 2022 Michael Erdely <mike@erdelynet.com>
# SPDX-License-Identifier: MIT
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand docker
assertHaveCommand bc
assertHaveCommand ip
assertHaveCommand awk
declare -A pids
declare -A time_start
declare -A cpu_start
declare -A rx_start
declare -A tx_start
declare -A br_start
declare -A bw_start
[[ $0 =~ .*_metric.sh ]] && mode=metric
# Either add the splunk user to the docker group or add the following to /etc/sudoers:
# splunk ALL=(root) NOPASSWD: /usr/bin/docker stats --no-stream --no-trunc --all
# splunk ALL=(root) NOPASSWD: /usr/bin/docker ps --all --no-trunc --format *
# splunk ALL=(root) NOPASSWD: /usr/bin/docker inspect -f *
docker_cmd=docker
if [ $(id -u) != 0 ]; then
! groups | grep -q "\bdocker\b" && docker_cmd="sudo -n $docker_cmd"
fi
docker_list=$($docker_cmd ps --all --no-trunc --format '{{ .ID }}')
header_string="ContainerId Name CPUPct MemUsage MemTotal MemPct NetRX RXps NetTX TXps BlockRead BRps BlockWrite BWps Pids"
metric_string=""
header_format="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"
string_format="%s\t%s\t%s\t%.2f\t%s\t%s\t%.2f\t%s\t%.2f\t%s\t%.2f\t%s\t%.2f\t%s\t%.2f\t%s\n"
json_format='{ "time": "%s", "ContainerId": "%s", "Name": "%s", "CPUPct": %.2f, "MemUsage": %s, "MemTotal": %s, "MemPct": %.2f, "NetRX": %s, "RXps": %.2f, "NetTX": %s, "TXps": %.2f, "BlockRead": %s, "BRps": %.2f, "BlockWrite": %s, "BWps": %.2f, "Pids": %s }\n'
if [ "$mode" = "metric" ]; then
metric_name=docker_metric
if [ ! -f "/etc/os-release" ] ; then
OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_')
OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1)
IP_address=$(ip addr show dev $(ip route show | awk 'BEGIN{m=1000}$1=="default"$0!~/ metric /{print $5;exit}$1=="default"{if($NF<m){m=$NF;i=$5}}END{print i}') | awk '$1=="inet"{print gensub(/\/[0-9]+/,"","g",$2)}')
else
OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d\= -f2 | tr ' ' '_' | cut -d\" -f2)
OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d\= -f2 | cut -d\" -f2)
IP_address=$(ip addr show dev $(ip route show | awk 'BEGIN{m=1000}$1=="default"$0!~/ metric /{print $5;exit}$1=="default"{if($NF<m){m=$NF;i=$5}}END{print i}') | awk '$1=="inet"{print gensub(/\/[0-9]+/,"","g",$2)}')
fi
[ -z "$OSName" ] && OSName="?"
[ $OSName = Arch_Linux ] && OS_version=rolling
[ -z "$OS_version" ] && OS_version="?"
header_string="$header_string OSName OS_version IP_address"
metric_string=" $OSName $OS_version $IP_address"
header_format="${header_format::-2}\t%s\t%s\t%s\n"
string_format="${string_format::-2}\t%s\t%s\t%s\n"
json_format='{ "time": "%s", "ContainerId": "%s", "Name": "%s", "CPUPct": %.2f, "MemUsage": %.2f, "MemTotal": %.2f, "MemPct": %.2f, "NetRX": %.2f, "RXps": %.2f, "NetTX": %.2f, "TXps": %.2f, "BlockRead": %.2f, "BRps": %.2f, "BlockWrite": %.2f, "BWps": %.2f, "Pids": %s, "OSName": "%s", "OS_version": "%s", "IP_address": "%s", "event": "metric" }\n'
fi
# Currently calculates CPU % over time; not right now
for id in $docker_list; do
[ ! -d /sys/fs/cgroup/system.slice/docker-$id.scope ] && continue
pids[$id]=$($docker_cmd inspect -f '{{ .State.Pid }}' $id)
read time_start[$id] _ < /proc/uptime
read _ cpu_start[$id] < /sys/fs/cgroup/system.slice/docker-$id.scope/cpu.stat
while read _if _rx _ _ _ _ _ _ _ _tx _ _ _ _ _ _ _ ; do
[ -z "$_if" ] && continue
[ -z "$_rx" ] && _rx=0
[ -z "$_tx" ] && _tx=0
if=$_if rx_start[$id]=$_rx tx_start[$id]=$_tx
done < /proc/${pids[$id]}/net/dev
br_start[$id]=0;bw_start[$id]=0
while read _ _br _bw _ _ _ _; do
[ -z "$_br" ] && _br=rbytes=0
[ -z "$_bw" ] && _bw=wbytes=0
br_start[$id]=$((${br_start[$id]}+${_br:7}))
bw_start[$id]=$((${bw_start[$id]}+${_bw:7}))
done < /sys/fs/cgroup/system.slice/docker-$id.scope/io.stat
done
sleep 2 # Sleep 2 seconds to give the script time to get CPU stats
MemTotal=$(awk '$1=="MemTotal:" {print $2*1024}' /proc/meminfo)
#printf "$header_format" $header_string
for id in $docker_list; do
name=$($docker_cmd inspect -f '{{ .Name }}' $id)
if [ ! -d /sys/fs/cgroup/system.slice/docker-$id.scope ]; then
printf "$json_format" $id ${name:1} 0 0 0 0 0 0 0 0 0 0 0 0 0$metric_string
continue
fi
read cpu_stop _ < /proc/uptime
read _ proc_stop < /sys/fs/cgroup/system.slice/docker-$id.scope/cpu.stat
while read _if _rx _ _ _ _ _ _ _ _tx _ _ _ _ _ _ _ ; do
[ -z "$_if" ] && continue
[ -z "$_rx" ] && _rx=0
[ -z "$_tx" ] && _tx=0
if=$_if NetRX=$_rx NetTX=$_tx
done < /proc/${pids[$id]}/net/dev
BlockRead=0;BlockWrite=0
while read _ _br _bw _ _ _ _; do
[ -z "$_br" ] && _br=rbytes=0
[ -z "$_bw" ] && _bw=wbytes=0
BlockRead=$((BlockRead+${_br:7}))
BlockWrite=$((BlockWrite+${_bw:7}))
done < /sys/fs/cgroup/system.slice/docker-$id.scope/io.stat
read MemUsage < /sys/fs/cgroup/system.slice/docker-$id.scope/memory.current
read Pids < /sys/fs/cgroup/system.slice/docker-$id.scope/pids.current
read _ CPU < /sys/fs/cgroup/cpu.stat
CpuUsage=$(echo "($proc_stop - ${cpu_start[$id]}) / ($cpu_stop * 1000000 - ${time_start[$id]} * 1000000) * 100" | bc -l)
RXps=$(echo "($NetRX - ${rx_start[$id]}) / ($cpu_stop * 1000000 - ${time_start[$id]} * 1000000) * 100" | bc -l)
TXps=$(echo "($NetTX - ${tx_start[$id]}) / ($cpu_stop * 1000000 - ${time_start[$id]} * 1000000) * 100" | bc -l)
BRps=$(echo "($BlockRead - ${br_start[$id]}) / ($cpu_stop * 1000000 - ${time_start[$id]} * 1000000) * 100" | bc -l)
BWps=$(echo "($BlockWrite - ${bw_start[$id]}) / ($cpu_stop * 1000000 - ${time_start[$id]} * 1000000) * 100" | bc -l)
printf "$json_format" "$(env TZ=UTC date "+%FT%T.%NZ")" $id ${name:1} $CpuUsage $MemUsage $MemTotal $(echo "$MemUsage*100/$MemTotal"|bc -l) $NetRX $RXps $NetTX $TXps $BlockRead $BRps $BlockWrite $BWps $Pids$metric_string
done

1
bin/docker_metric.sh Symbolic link
View file

@ -0,0 +1 @@
docker.sh

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -9,13 +10,14 @@ FORMAT='{key = $1; if (NF == 1) {value = "<notAvailable>"} else {value = $2; for
PRINTF='{printf("%-20s %-s\n", key, value)}'
if [ "$KERNEL" = "Linux" ] ; then
TMP_ERROR_FILTER_FILE=$SPLUNK_HOME/var/run/splunk/unix_hardware_error_tmpfile # For filtering out lshw warning from stderr
TMP_ERROR_FILTER_FILE=$(mktemp) # For filtering out lshw warning from stderr
queryHaveCommand ip
FOUND_IP=$?
# CPUs
CPU_TYPE=$(awk -F: '/model name/ {print $2; exit}' /proc/cpuinfo 2>>"$TEE_DEST")
CPU_CACHE=$(awk -F: '/cache size/ {print $2; exit}' /proc/cpuinfo 2>>"$TEE_DEST")
CPU_COUNT=$(grep -c processor /proc/cpuinfo 2>>"$TEE_DEST")
[ -z "$CPU_TYPE" ] && [ -r /proc/device-tree/compatible ] && CPU_TYPE=$(cat /proc/device-tree/compatible | tr '\0' ',')
# HDs
# shellcheck disable=SC2010
for deviceBasename in $(ls /sys/block | grep -E -v '^(dm|md|ram|sr|loop)')
@ -187,6 +189,29 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
OUTPUT=$(swapinfo -tm)
MEMORY_REAL=$(echo "$OUTPUT" | awk '$1=="memory" {print $2 " MB"; exit}')
MEMORY_SWAP=$(echo "$OUTPUT" | awk '$1=="dev" {print $2 " MB"; exit}')
elif [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand sysctl
assertHaveCommand df
assertHaveCommand ifconfig
assertHaveCommand dmesg
assertHaveCommand top
# CPUs
CPU_TYPE=$(sysctl -n hw.model)
CPU_CACHE=
CPU_COUNT=$(sysctl -n hw.ncpu)
# HDs
HARD_DRIVES=$(df -h | awk '/^\/dev/ {sub("^.*\134/", "", $1); drives[$1] = $2} END {for(d in drives) printf("%s: %s; ", d, drives[d])}')
# NICs
IFACE_NAME=$(ifconfig -a | awk '/^[a-z0-9]+: / {sub(":", "", $1); iface=$1} /media: / {print iface}')
for NIC in $IFACE_NAME; do
NIC=$(echo $NIC | sed -E 's/[0-9]+$//')
NIC_TYPE="$NIC_TYPE,$(whatis $NIC | sed -E 's/^.* - //')"
done
NIC_TYPE=${NIC_TYPE#,}
NIC_COUNT=$(echo $IFACE_NAME | wc -w)
# memory
MEMORY_REAL=$(sysctl -n hw.physmem)
MEMORY_SWAP=$(systat -b swap | gawk '/^DISK/{p=1;next}p==1{swap+=$2}END{print int(swap/2)}')
elif [ "$KERNEL" = "FreeBSD" ] ; then
assertHaveCommand sysctl
assertHaveCommand df
@ -194,9 +219,9 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
assertHaveCommand dmesg
assertHaveCommand top
# CPUs
CPU_TYPE=$(sysctl hw.model | sed 's/^.*: //')
CPU_TYPE=$(sysctl -n hw.model)
CPU_CACHE=
CPU_COUNT=$(sysctl hw.ncpu | sed 's/^.*: //')
CPU_COUNT=$(sysctl -n hw.ncpu)
# HDs
HARD_DRIVES=$(df -h | awk '/^\/dev/ {sub("^.*\134/", "", $1); drives[$1] = $2} END {for(d in drives) printf("%s: %s; ", d, drives[d])}')
# NICs
@ -204,7 +229,7 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
NIC_TYPE=$(dmesg | awk '(index($0, iface) && index($0, " port ")) {sub("^.*<", ""); sub(">.*$", ""); print $0}' iface="$IFACE_NAME" | head -1)
NIC_COUNT=$(ifconfig -a | grep -c media)
# memory
MEMORY_REAL=$(sysctl hw.physmem | awk '{print $2/(1024*1024) "MB"}')
MEMORY_REAL=$(sysctl -n hw.physmem)
MEMORY_SWAP=$(top -Sb 0 | awk '/^Swap: / {print $2 "B"}')
fi

View file

@ -6,15 +6,17 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors TXbytes TXerrors Speed Duplex'
#HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors TXbytes TXerrors Speed Duplex'
HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors RXdropped TXbytes TXerrors TXdropped Speed Duplex'
FORMAT='{mac = length(mac) ? mac : "?"; collisions = length(collisions) ? collisions : "?"; RXbytes = length(RXbytes) ? RXbytes : "?"; RXerrors = length(RXerrors) ? RXerrors : "?"; TXbytes = length(TXbytes) ? TXbytes : "?"; TXerrors = length(TXerrors) ? TXerrors : "?"; speed = length(speed) ? speed : "?"; duplex = length(duplex) ? duplex : "?"}'
PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-16s %-16s %-12s %-12s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, TXbytes, TXerrors, speed, duplex}'
#PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-16s %-16s %-12s %-12s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, TXbytes, TXerrors, speed, duplex}'
PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-18s %-16s %-16s %-18s %-12s %-12s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, (RXdropped == "") ? 0 : RXdropped, TXbytes, TXerrors, (TXdropped == "") ? 0 : TXdropped, speed, duplex}'
if [ "$KERNEL" = "Linux" ] ; then
OS_FILE=/etc/os-release
HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors RXdropped TXbytes TXerrors TXdropped Speed Duplex'
PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-18s %-16s %-16s %-18s %-12s %-12s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, RXdropped, TXbytes, TXerrors, TXdropped, speed, duplex}'
#HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors RXdropped TXbytes TXerrors TXdropped Speed Duplex'
#PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-18s %-16s %-16s %-18s %-12s %-12s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, RXdropped, TXbytes, TXerrors, TXdropped, speed, duplex}'
queryHaveCommand ip
FOUND_IP=$?
if [ $FOUND_IP -eq 0 ]; then
@ -253,7 +255,7 @@ if [ "$KERNEL" = "Linux" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
@ -322,12 +324,13 @@ if [ "$KERNEL" = "Linux" ] ; then
GET_MAC='{if ($0 ~ /ether /) { mac = $2; } else if ( NR == 1 ) { mac = $5; }}'
fi
if [ "$DUPLEX" != 'error' ] && [ "$SPEED" != 'error' ]; then
$CMD "$iface" | tee -a "$TEE_DEST" | awk "$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF" name="$iface" speed="$SPEED" duplex="$DUPLEX" mac="$MAC"
output="$output$($CMD "$iface" | tee -a "$TEE_DEST" | awk "$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF" name="$iface" speed="$SPEED" duplex="$DUPLEX" mac="$MAC")\n"
echo "Cmd = [$CMD $iface]; | awk '$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF' name=$iface speed=$SPEED duplex=$DUPLEX mac=$MAC" >> "$TEE_DEST"
else
echo "ERROR: cat command failed for interface $iface" >> "$TEE_DEST"
fi
done
printf "$output" | column -t
elif [ "$KERNEL" = "SunOS" ] ; then
assertHaveCommandGivenPath /usr/sbin/ifconfig
@ -346,7 +349,7 @@ elif [ "$KERNEL" = "SunOS" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
@ -358,9 +361,10 @@ elif [ "$KERNEL" = "SunOS" ] ; then
else
CMD_DESCRIBE_INTERFACE="eval kstat -n $iface ; /usr/sbin/ifconfig $iface 2>/dev/null"
fi
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | $AWK '$GET_ALL $FORMAT $PRINTF' name=$iface node=$NODE" >> "$TEE_DEST"
done
printf "$output" | column -t
elif [ "$KERNEL" = "AIX" ] ; then
assertHaveCommandGivenPath /usr/sbin/ifconfig
assertHaveCommandGivenPath /usr/bin/netstat
@ -378,16 +382,17 @@ elif [ "$KERNEL" = "AIX" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
echo "Cmd = [$CMD_LIST_INTERFACES]" >> "$TEE_DEST"
NODE=$(uname -n)
CMD_DESCRIBE_INTERFACE="eval netstat -v $iface ; /usr/sbin/ifconfig $iface"
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | $AWK '$GET_ALL $FORMAT $PRINTF' name=$iface node=$NODE" >> "$TEE_DEST"
done
printf "$output"
elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
@ -437,15 +442,16 @@ elif [ "$KERNEL" = "Darwin" ] ; then
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
echo "Cmd = [$CMD_LIST_INTERFACES]; | awk '$CHOOSE_ACTIVE' | $UNIQUE" >> "$TEE_DEST"
CMD_DESCRIBE_INTERFACE="eval ifconfig $iface ; netstat -b -I $iface"
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk "$GET_ALL $PRINTF" name="$iface"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk "$GET_ALL $PRINTF" name="$iface")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | awk '$GET_ALL $PRINTF' name=$iface" >> "$TEE_DEST"
done
printf "$output" | column -t
elif [ "$KERNEL" = "HP-UX" ] ; then
assertHaveCommand ifconfig
assertHaveCommand lanadmin
@ -466,9 +472,30 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
out=$($CMD | awk "$LANSCAN_AWK $GET_IP4 $GET_IP6 $GET_SPEED_DUPLEX $PRINTF $FILL_BLANKS")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
echo "$out"
printf "$HEADER\n$out\n"
fi
elif [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
CMD_LIST_INTERFACES='ifconfig -a'
# shellcheck disable=SC2016
CHOOSE_ACTIVE='/^[a-z0-9]+: / {sub(":", "", $1); iface=$1} /media: / {print iface}'
UNIQUE='sort -u'
# shellcheck disable=SC2016
GET_MAC='{$1 == "lladdr" && mac = $2}'
# shellcheck disable=SC2016
GET_IP='/ (netmask|prefixlen) / {for (i=1; i<=NF; i++) {if ($i == "inet") IPv4 = $(i+1); if ($i == "inet6") IPv6 = $(i+1)}}'
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
output="$HEADER\n"
fi
for iface in $out
do
output="$output$iface $(ifconfig $iface | awk "$GET_MAC $GET_IP END {printf \"%s %s %s\", mac, IPv4, IPv6}") $(echo $(netstat -bnI $iface -w1 | head -n4 | tail -n1) $(netstat -neI $iface -w1 | head -n4 | tail -n1) | awk "{printf \"%s %s %s %s %s %s %s\", \$9, \$1, 0, \$6, \$2, \$8, 0}") auto auto\n"
done
printf "$output" | column -t
elif [ "$KERNEL" = "FreeBSD" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
@ -515,14 +542,15 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
echo "Cmd = [$CMD_LIST_INTERFACES]; | awk '$CHOOSE_ACTIVE' | $UNIQUE" >> "$TEE_DEST"
CMD_DESCRIBE_INTERFACE="eval ifconfig $iface ; netstat -b -I $iface"
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk "$GET_ALL $PRINTF" name="$iface"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk "$GET_ALL $PRINTF" name="$iface")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | awk '$GET_ALL $PRINTF' name=$iface" >> "$TEE_DEST"
done
printf "$output" | column -t
fi
# jscpd:ignore-end

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -6,6 +7,8 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
HEADER='Name MAC inetAddr inet6Addr Collisions RXbytes RXerrors TXbytes TXerrors Speed Duplex OSName OS_version IP_address IPv6_Address'
FORMAT='{mac = length(mac) ? mac : "?"; collisions = length(collisions) ? collisions : "?"; RXbytes = length(RXbytes) ? RXbytes : "?"; RXerrors = length(RXerrors) ? RXerrors : "?"; TXbytes = length(TXbytes) ? TXbytes : "?"; TXerrors = length(TXerrors) ? TXerrors : "?"; speed = length(speed) ? speed : "?"; duplex = length(duplex) ? duplex : "?"}'
PRINTF='END {printf "%-10s %-17s %-15s %-42s %-10s %-16s %-16s %-16s %-16s %-12s %-12s %-35s %15s %-16s %-42s\n", name, mac, IPv4, IPv6, collisions, RXbytes, RXerrors, TXbytes, TXerrors, speed, duplex, OSName, OS_version, IP_address, IPv6_Address}'
@ -18,9 +21,9 @@ if [ "$KERNEL" = "Linux" ] ; then
queryHaveCommand ip
FOUND_IP=$?
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
fi
if [ $FOUND_IP -eq 0 ]; then
CMD_LIST_INTERFACES="eval ip -s a | tee $TEE_DEST|grep 'state UP' | grep mtu | grep -Ev lo | tee -a $TEE_DEST | cut -d':' -f2 | tee -a $TEE_DEST | cut -d '@' -f 1 | tee -a $TEE_DEST | sort -u | tee -a $TEE_DEST"
@ -259,7 +262,7 @@ if [ "$KERNEL" = "Linux" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
@ -324,12 +327,13 @@ if [ "$KERNEL" = "Linux" ] ; then
fi
if [ "$DUPLEX" != 'error' ] && [ "$SPEED" != 'error' ]; then
# shellcheck disable=SC2086
$CMD "$iface" | tee -a "$TEE_DEST" | awk $DEFINE "$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF" name="$iface" speed="$SPEED" duplex="$DUPLEX" mac="$MAC"
output="$output$($CMD "$iface" | tee -a "$TEE_DEST" | awk $DEFINE "$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF" name="$iface" speed="$SPEED" duplex="$DUPLEX" mac="$MAC")\n"
echo "Cmd = [$CMD $iface]; | awk $DEFINE '$BEGIN $GET_MAC $GET_ALL $FILL_BLANKS $PRINTF' name=$iface speed=$SPEED duplex=$DUPLEX mac=$MAC" >> "$TEE_DEST"
else
echo "ERROR: cat command failed for interface $iface" >> "$TEE_DEST"
fi
done
printf "$output" | column -t
elif [ "$KERNEL" = "SunOS" ] ; then
assertHaveCommandGivenPath /usr/sbin/ifconfig
@ -351,7 +355,7 @@ elif [ "$KERNEL" = "SunOS" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
@ -364,9 +368,10 @@ elif [ "$KERNEL" = "SunOS" ] ; then
CMD_DESCRIBE_INTERFACE="eval kstat -n $iface ; /usr/sbin/ifconfig $iface 2>/dev/null"
fi
# shellcheck disable=SC2086
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK $DEFINE "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK $DEFINE "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | $AWK $DEFINE '$GET_ALL $FORMAT $PRINTF' name=$iface node=$NODE" >> "$TEE_DEST"
done
printf "$output" | column -t
elif [ "$KERNEL" = "AIX" ] ; then
assertHaveCommandGivenPath /usr/sbin/ifconfig
assertHaveCommandGivenPath /usr/bin/netstat
@ -388,7 +393,7 @@ elif [ "$KERNEL" = "AIX" ] ; then
out=$($CMD_LIST_INTERFACES)
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
@ -396,9 +401,10 @@ elif [ "$KERNEL" = "AIX" ] ; then
NODE=$(uname -n)
CMD_DESCRIBE_INTERFACE="eval netstat -v $iface ; /usr/sbin/ifconfig $iface"
# shellcheck disable=SC2086
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK $DEFINE "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | $AWK $DEFINE "$GET_ALL $FORMAT $PRINTF" name="$iface" node="$NODE")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | $AWK $DEFINE '$GET_ALL $FORMAT $PRINTF' name=$iface node=$NODE" >> "$TEE_DEST"
done
printf "$output" | column -t
elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
@ -450,16 +456,17 @@ elif [ "$KERNEL" = "Darwin" ] ; then
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
echo "Cmd = [$CMD_LIST_INTERFACES]; | awk '$CHOOSE_ACTIVE' | $UNIQUE" >> "$TEE_DEST"
CMD_DESCRIBE_INTERFACE="eval ifconfig $iface ; netstat -b -I $iface"
# shellcheck disable=SC2086
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk $DEFINE "$GET_ALL $PRINTF" name="$iface"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk $DEFINE "$GET_ALL $PRINTF" name="$iface")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | awk $DEFINE '$GET_ALL $PRINTF' name=$iface" >> "$TEE_DEST"
done
printf "$output" | column -t
elif [ "$KERNEL" = "HP-UX" ] ; then
assertHaveCommand ifconfig
assertHaveCommand lanadmin
@ -481,9 +488,33 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
out=$($CMD | awk "$LANSCAN_AWK $GET_IP4 $GET_IP6 $GET_SPEED_DUPLEX $PRINTF $FILL_BLANKS")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
echo "$out"
printf "$HEADER\n$out\n" | column -t
fi
elif [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
CMD_LIST_INTERFACES='ifconfig -a'
# shellcheck disable=SC2016
CHOOSE_ACTIVE='/^[a-z0-9]+: / {sub(":", "", $1); iface=$1} /media: / {print iface}'
UNIQUE='sort -u'
# shellcheck disable=SC2016
GET_MAC='{$1 == "lladdr" && mac = $2}'
# shellcheck disable=SC2016
GET_IP='/ (netmask|prefixlen) / {for (i=1; i<=NF; i++) {if ($i == "inet") IPv4 = $(i+1); if ($i == "inet6") IPv6 = $(i+1)}}'
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
INT=$(netstat -nr | awk '$1 == "default" {print $NF; exit}')
IP4=$(ifconfig $INT | awk '$1=="inet"{print $2;p=1;exit}END{if (p!=1) print "<n/a>"}')
IP6=$(ifconfig $INT | awk '$1=="inet6" && $2!~/%vio0$/{print $2;p=1;exit}END{if (p!=1) print "<n/a>"}')
if [ "$lines" -gt 0 ]; then
output="$HEADER\n"
fi
for iface in $out
do
output="$output"$iface $(ifconfig $iface | awk "$GET_MAC $GET_IP END {printf \"%s %s %s\", mac, IPv4, IPv6}") $(echo $(netstat -bnI $iface -w1 | head -n4 | tail -n1) $(netstat -neI $iface -w1 | head -n4 | tail -n1) | awk "{printf \"%s %s %s %s %s\", \$9, \$1, \$6, \$2, \$8}") auto auto $(uname -s) $(uname -r) $IP4 $IP6\n"
done
printf "$output" | column -t
elif [ "$KERNEL" = "FreeBSD" ] ; then
assertHaveCommand ifconfig
assertHaveCommand netstat
@ -533,15 +564,16 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
out=$($CMD_LIST_INTERFACES | tee "$TEE_DEST" | awk "$CHOOSE_ACTIVE" | $UNIQUE | tee -a "$TEE_DEST")
lines=$(echo "$out" | wc -l)
if [ "$lines" -gt 0 ]; then
echo "$HEADER"
output="$HEADER\n"
fi
for iface in $out
do
echo "Cmd = [$CMD_LIST_INTERFACES]; | awk '$CHOOSE_ACTIVE' | $UNIQUE" >> "$TEE_DEST"
CMD_DESCRIBE_INTERFACE="eval ifconfig $iface ; netstat -b -I $iface"
# shellcheck disable=SC2086
$CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk $DEFINE "$GET_ALL $PRINTF" name="$iface"
output="$output$($CMD_DESCRIBE_INTERFACE | tee -a "$TEE_DEST" | awk $DEFINE "$GET_ALL $PRINTF" name="$iface")\n"
echo "Cmd = [$CMD_DESCRIBE_INTERFACE]; | awk $DEFINE '$GET_ALL $PRINTF' name=$iface" >> "$TEE_DEST"
done
printf "$output" | column -t
fi
# jscpd:ignore-end

View file

@ -7,6 +7,8 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
if [ "$KERNEL" = "Linux" ] ; then
CMD='iostat -xky 1 1'
assertHaveCommand "$CMD"
@ -22,6 +24,12 @@ elif [ "$KERNEL" = "AIX" ] ; then
assertHaveCommand "$CMD"
# considers the disks, kb_read and kb_wrtn columns and returns output of the second interval
FILTER='/^cd/ {next} /Disks/ && /Kb_read/ && /Kb_wrtn/ {f++;} f==2'
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD='systat -B iostat'
assertHaveCommand "$CMD"
HEADER="Device rB/s wB/s r/s w/s"
HEADERIZE="BEGIN {print \"$HEADER\"}"
FILTER=$HEADERIZE'/^[^ \t]/ && !/^(DEVICE|Totals)/{printf "%-7s %.2f %.2f %d %d\n", $1, $2/1024, $3/1024, $4, $5}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
CMD='iostat -x -c 2'
assertHaveCommand "$CMD"
@ -43,10 +51,10 @@ elif [ "$KERNEL" = "Darwin" ] ; then
LATENCY='function getLatency(disk) {read=getDeltaPS(disk,"Latency Time (Read)"); write=getDeltaPS(disk,"Latency Time (Write)"); return expr read + write;}'
FUNC2='function getAllDeltasPS(disk) {rReq_PS=getDeltaPS(disk,"Operations (Read)"); wReq_PS=getDeltaPS(disk,"Operations (Write)"); rKB_PS=getDeltaPS(disk,"Bytes (Read)")/1024; wKB_PS=getDeltaPS(disk,"Bytes (Write)")/1024; avgWaitMillis=getLatency(disk);}'
SCRIPT="$HEADERIZE $FILTER $FUNC1 $LATENCY $FUNC2 END {$FORMAT for (device in devices) {getAllDeltasPS(device); $PRINTF}}"
$CMD | tee "$TEE_DEST" | awk "$SCRIPT" header="$HEADER"
$CMD | tee "$TEE_DEST" | awk "$SCRIPT" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | awk '$SCRIPT' header=\"$HEADER\"" >> "$TEE_DEST"
exit 0
fi
$CMD | tee "$TEE_DEST" | $AWK "$FILTER"
$CMD | tee "$TEE_DEST" | $AWK "$FILTER" | column -t
echo "Cmd = [$CMD]; | $AWK '$FILTER'" >> "$TEE_DEST"

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -7,13 +8,15 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
if [ "$KERNEL" = "Linux" ] ; then
CMD='iostat -xky 1 1'
assertHaveCommand "$CMD"
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
fi
FILTER='/Device/ && /r\/s/ && /w\/s/ {f=1;}f'
# shellcheck disable=SC2016
@ -34,6 +37,13 @@ elif [ "$KERNEL" = "AIX" ] ; then
FILTER='/^cd/ {next} /Disks/ && /Kb_read/ && /Kb_wrtn/ {f++;} f==2'
# shellcheck disable=SC2016
PRINTF='{if ($0~/Disks/ && /Kb_read/ && /Kb_wrtn/) {printf "%s OSName OS_version IP_address \n", $0} else if (NF!=0) {printf "%s %s %s %s\n", $0, OSName, OS_version/1000, IP_address}}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD='systat -B iostat'
assertHaveCommand "$CMD"
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig $(netstat -nr | awk '$1 == "default" {print $NF; exit}') | awk '$1=="inet"{print $2;p=1;exit}END{if (p!=1) print "<n/a>"}')"
HEADER="Device rB/s wB/s r/s w/s OSName OS_version IP_address"
HEADERIZE="BEGIN {print \"$HEADER\"}"
FILTER=$HEADERIZE'/^[^ \t]/ && !/^(DEVICE|Totals)/{printf "%-7s %.2f %.2f %d %d %s %s %s\n", $1, $2/1024, $3/1024, $4, $5, OSName, OS_version, IP_address}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
CMD='iostat -x -c 2'
assertHaveCommand "$CMD"
@ -58,10 +68,10 @@ elif [ "$KERNEL" = "Darwin" ] ; then
FUNC2='function getAllDeltasPS(disk) {rReq_PS=getDeltaPS(disk,"Operations (Read)"); wReq_PS=getDeltaPS(disk,"Operations (Write)"); rKB_PS=getDeltaPS(disk,"Bytes (Read)")/1024; wKB_PS=getDeltaPS(disk,"Bytes (Write)")/1024; avgWaitMillis=getLatency(disk);}'
SCRIPT="$HEADERIZE $FILTER $FUNC1 $LATENCY $FUNC2 END {$FORMAT for (device in devices) {getAllDeltasPS(device); $PRINTF}}"
# shellcheck disable=SC2086
$CMD | tee "$TEE_DEST" | awk $DEFINE "$SCRIPT" header="$HEADER"
$CMD | tee "$TEE_DEST" | awk $DEFINE "$SCRIPT" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | awk $DEFINE '$SCRIPT' header=\"$HEADER\"" >> "$TEE_DEST"
exit 0
fi
# shellcheck disable=SC2086
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$FILTER $PRINTF"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$FILTER $PRINTF" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE '$FILTER'" >> "$TEE_DEST"

View file

@ -5,22 +5,35 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
HEADER='USERNAME FROM LATEST'
HEADER='USERNAME FROM LATEST DURATION'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-30s %-30.30s %-s\n", username, from, latest}'
PRINTF='{printf "%-30s %-30.30s %-30.30s %-s\n", username, from, latest, duration}'
if [ "$KERNEL" = "Linux" ] ; then
CMD='last -iw'
# shellcheck disable=SC2016
FILTER='{if ($0 == "") exit; if ($1 ~ /reboot|shutdown/ || $1 in users) next; users[$1]=1}'
# shellcheck disable=SC2016
FORMAT='{username = $1; from = (NF==10) ? $3 : "<console>"; latest = $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3)}'
# Extracts duration values from the 10th column of the `last` command output.
# If the session is `still running` or `still logged in`, "N/A" is set as the default value.
# This approach is applied to all supported kernels in the script.
FORMAT='{
username = $1;
from = (NF>=10) ? $3 : "<console>";
latest = (NF >= 10 && ($7 == "gone" || $8 == "gone" || $9 == "gone")) ? $(NF-7) " " $(NF-6) " " $(NF-5) " " $(NF-4) : $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3);
duration = (NF >= 10 && $10 != "still" && $10 != "logged" && $10 != "running" && $10 != "in" && $10 != "" && $10 != "gone" && $10 != "no" && $10 != "logout") ? $10 : "N/A";
}'
elif [ "$KERNEL" = "SunOS" ] ; then
CMD='last -n 999'
# shellcheck disable=SC2016
FILTER='{if ($0 == "") exit; if ($1 ~ /reboot|shutdown/ || $1 in users) next; users[$1]=1}'
# shellcheck disable=SC2016
FORMAT='{username = $1; from = (NF==10) ? $3 : "<console>"; latest = $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3)}'
FORMAT='{
username = $1;
from = (NF>=10) ? $3 : "<console>";
latest = (NF >= 10 && ($7 == "gone" || $8 == "gone" || $9 == "gone")) ? $(NF-7) " " $(NF-6) " " $(NF-5) " " $(NF-4) : $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3);
duration = (NF >= 10 && $10 != "still" && $10 != "logged" && $10 != "running" && $10 != "in" && $10 != "" && $10 != "gone" && $10 != "no" && $10 != "logout") ? $10 : "N/A";
}'
elif [ "$KERNEL" = "AIX" ] ; then
failUnsupportedScript
elif [ "$KERNEL" = "Darwin" ] ; then
@ -28,7 +41,23 @@ elif [ "$KERNEL" = "Darwin" ] ; then
# shellcheck disable=SC2016
FILTER='{if ($0 == "") exit; if ($1 ~ /reboot|shutdown/ || $1 in users) next; users[$1]=1}'
# shellcheck disable=SC2016
FORMAT='{username = $1; from = ($0 !~ / /) ? $3 : "<console>"; latest = $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3)}'
FORMAT='{
username = $1;
from = ($0 !~ / /) ? $3 : "<console>";
latest = (NF >= 10 && ($7 == "gone" || $8 == "gone" || $9 == "gone")) ? $(NF-7) " " $(NF-6) " " $(NF-5) " " $(NF-4) : $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3);
duration = (NF >= 10 && $10 != "still" && $10 != "logged" && $10 != "running" && $10 != "in" && $10 != "" && $10 != "gone" && $10 != "no" && $10 != "logout") ? $10 : "N/A";
}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD='last'
# shellcheck disable=SC2016
FILTER='{if ($0 == "") exit; if ($1 ~ /reboot|shutdown/ || $1 in users) next; users[$1]=1}'
# shellcheck disable=SC2016
FORMAT='{
username = $1;
from = (NF>=10) ? $3 : "<console>";
latest = (NF >= 10 && ($7 == "gone" || $8 == "gone" || $9 == "gone")) ? $(NF-7) " " $(NF-6) " " $(NF-5) " " $(NF-4) : $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3);
duration = (NF >= 10 && $10 != "still" && $10 != "logged" && $10 != "running" && $10 != "in" && $10 != "" && $10 != "gone" && $10 != "no" && $10 != "logout") ? $10 : "N/A";
}'
elif [ "$KERNEL" = "HP-UX" ] ; then
CMD='lastb -Rx'
# shellcheck disable=SC2016
@ -36,9 +65,16 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
# shellcheck disable=SC2016
FILTER='{if ($1 == "BTMPS_FILE") next; if (NF==0) next; if (NF<=6) next;}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
CMD='lastlogin'
CMD='last -w'
# shellcheck disable=SC2016
FORMAT='{username = $1; from = (NF==8) ? $3 : "<console>"; latest=$(NF-4) " " $(NF-3) " " $(NF-2) " " $(NF-1) " " $NF}'
FILTER='{if ($0 == "") exit; if ($1 ~ /reboot|shutdown/ || $1 in users) next; users[$1]=1}'
# shellcheck disable=SC2016
FORMAT='{
username = $1;
from = (NF>=10) ? $3 : "<console>";
latest = (NF >= 10 && ($7 == "gone" || $8 == "gone" || $9 == "gone")) ? $(NF-7) " " $(NF-6) " " $(NF-5) " " $(NF-4) : $(NF-6) " " $(NF-5) " " $(NF-4) " " $(NF-3);
duration = (NF >= 10 && $10 != "still" && $10 != "logged" && $10 != "running" && $10 != "in" && $10 != "" && $10 != "gone" && $10 != "no" && $10 != "logout") ? $10 : "N/A";
}'
fi
assertHaveCommand $CMD

View file

@ -5,6 +5,11 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
if [ "$KERNEL" = "OpenBSD" ] ; then
fstat | awk '/^USER/{print "COMMAND PID USER FD MOUNT"} $5 ~ /^\// {print $2, $3, $1, $4, $5} $5 !~ /^\// && !/^USER/ {print $2, $3, $1, $4, $5, $6, $7, $8, $9, $10, $11}'
exit 0
fi
assertHaveCommand lsof
CMD='lsof -nPs +c 0'

View file

@ -39,7 +39,7 @@ elif [ "$KERNEL" = "Darwin" ] ; then
FORMAT='{gsub("[46]", "", $1)}'
elif [ "$KERNEL" = "HP-UX" ] ; then
CMD='eval netstat -an | egrep "tcp|udp"'
elif [ "$KERNEL" = "FreeBSD" ] ; then
elif [ "$KERNEL" = "FreeBSD" ] || [ "$KERNEL" = "OpenBSD" ] ; then
# shellcheck disable=SC2089
CMD='eval netstat -an | egrep "tcp|udp"'
# shellcheck disable=SC2016

View file

@ -5,6 +5,8 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
HEADER='Mount Path r_op/s w_op/s r_KB/s w_KB/s rpc_backlog r_avg_RTT w_avg_RTT r_avg_exe w_avg_exe'
HEADERIZE="BEGIN {print \"$HEADER\"}"
@ -44,11 +46,11 @@ if [ "$KERNEL" = "Linux" ] ; then
fi
# Below condition is added to handle the case of Ubuntu OS
if [ -e $OS_FILE ] && (awk -F'=' '/ID=/ {print $2}' $OS_FILE | grep -q ubuntu);
if [ -e "$OS_FILE" ] && (awk -F'=' '/ID=/ {print $2}' "$OS_FILE" | grep -Eq 'rocky|ubuntu|almalinux|ol');
then
# shellcheck disable=SC2016
OS_RELEASE=$($AWK -F= '/VERSION_ID=/ {print $2}' $OS_FILE)
if [ "$OS_RELEASE" = "\"18.04\"" ] || [ "$OS_RELEASE" = "\"20.04\"" ] || [ "$OS_RELEASE" = "\"22.04\"" ] ; then # Ubuntu 18.04, 20.04 and 22.04
OS_RELEASE=$(awk -F= '/^ID=/ {gsub(/"/, "", $2); id=$2} /^VERSION_ID=/ {gsub(/"/, "", $2); ver=$2} END {print id ":" ver}' "$OS_FILE")
if [ "$OS_RELEASE" = "ubuntu:18.04" ] || [ "$OS_RELEASE" = "ubuntu:20.04" ] || [ "$OS_RELEASE" = "ubuntu:22.04" ] || [ "$OS_RELEASE" = "rocky:9.5" ] || [ "$OS_RELEASE" = "almalinux:9.5" ] || [ "$OS_RELEASE" = "ol:8.9" ] ; then # Ubuntu 18.04, 20.04 and 22.04 # Rocky or AlmaLinux 9.5 # Oracle Linux 8.9
# shellcheck disable=SC2016
FORMAT='{
if (NR%10==2){

View file

@ -52,7 +52,7 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
FORMAT='{gsub("[46]", "", $1); proto=$1; sub("^.*[^0-9]", "", $4); port=$4}'
# shellcheck disable=SC2016
FILTER='{if ($4 == "") next}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
elif [ "$KERNEL" = "FreeBSD" ] || [ "$KERNEL" = "OpenBSD" ] ; then
# shellcheck disable=SC2089
CMD='eval netstat -ln | egrep "^tcp|^udp"'
HEADERIZE="BEGIN {print \"$HEADER\"}"

View file

@ -5,12 +5,15 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
HEADER='NAME VERSION RELEASE ARCH VENDOR GROUP'
HEADERIZE="BEGIN {print \"$HEADER\"}"
PRINTF='{printf "%-55.55s %-20.20s %-20.20s %-10.10s %-30.30s %-20s\n", name, version, release, arch, vendor, group}'
CMD='echo There is no flavor-independent command...'
if [ "$KERNEL" = "Linux" ] ; then
OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2)
if $DEBIAN; then
CMD1="eval dpkg-query -W -f='"
# shellcheck disable=SC2016
@ -19,6 +22,10 @@ if [ "$KERNEL" = "Linux" ] ; then
CMD=$CMD1$CMD2$CMD3
# shellcheck disable=SC2016
FORMAT='{name=$1;version=$2;sub("\\.?[^0-9\\.:\\-].*$", "", version); release=$2; sub("^[0-9\\.:\\-]*","",release); if(release=="") {release="?"}; arch=$3; if (NF>3) {sub("^.*:\\/\\/", "", $4); sub("^www\\.", "", $4); sub("\\/.*$", "", $4); vendor=$4} else {vendor="?"} group="?"}'
elif [ "$OSName" = "Arch_Linux" ] || [ "$OSName" = "Arch_Linux_ARM" ]; then
CMD="eval pacman -Q"
# shellcheck disable=SC2016
FORMAT="{name=\$1;version=\$2; release=\"?\"; arch=\"$(eval uname -m | sed -r "s/(armv7l|aarch64)/arm64/;s/x86_64/amd64/")\"; vendor=\"?\"; group=\"?\"}"
else
CMD='eval rpm --query --all --queryformat "%-56{name} %-21{version} %-21{release} %-11{arch} %-31{vendor} %-{group}\n"'
# shellcheck disable=SC2016
@ -46,6 +53,12 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
FILTER='/^#/ {next} $1=="" {next}'
# shellcheck disable=SC2016
FORMAT='{release="?"; group="?"; vendor="?"; name=$1; version=$2; arch=$3} NF==4 {vendor=$4}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD=pkg_info
HEADER='NAME VERSION ARCH '
HEADERIZE="BEGIN {print \"$HEADER\"; arch=\"$(arch -s)\"}"
#PRINTF='{ printf "%-50s %-50s %s\n",$1,$2,$3}'
PRINTF='{name=gensub(/-[0-9].*$/,"",1,$1); suffix=gensub(/^.*-([0-9][^-]*)/,"",1,$1); if (suffix!="") suffix="," suffix; version=gensub(/^.*-([0-9][^-]*)-?.*$/,"\\1",1,$1); printf "%-50s %-50s %s\n", name suffix, version, arch}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
# the below syntax is valid when using zsh, bash, ksh
if [[ $KERNEL_RELEASE =~ 10.* ]] || [[ $KERNEL_RELEASE =~ 11.* ]] || [[ $KERNEL_RELEASE =~ 12.* ]] || [[ $KERNEL_RELEASE =~ 13.* ]]; then
@ -63,5 +76,5 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
fi
assertHaveCommand "$CMD"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $SEPARATE_RECORDS $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FILTER $FORMAT $SEPARATE_RECORDS $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$HEADERIZE $FILTER $FORMAT $SEPARATE_RECORDS $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -5,6 +5,8 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
CMD='netstat -s'
HEADER=' IPdropped TCPrexmits TCPreorder TCPpktRecv TCPpktSent UDPpktLost UDPunkPort UDPpktRecv UDPpktSent'
HEADERIZE="BEGIN {print \"$HEADER\"}"
@ -65,7 +67,7 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
SECTION_TCP='inTCP && /retransmited$/ {TCPrexmits=$1} inTCP && /out of order/ {TCPreorder=$1} inTCP && /[0-9] packets received$/ {TCPpktRecv=$1} inTCP && /[0-9] packets sent$/ {TCPpktSent=$1}'
# shellcheck disable=SC2016
SECTION_UDP='inUDP && /packets received/ {UDPpktRecv=$1} inUDP && /packets sent/ {UDPpktSent=$1} inUDP && /packet receive errors/ {UDPpktLost=$1} inUDP && /packets to unknown port received/ {UDPunkPort=$1}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
elif [ "$KERNEL" = "FreeBSD" ] || [ "$KERNEL" = "OpenBSD" ] ; then
# shellcheck disable=SC2016
FIGURE_SECTION='/^ip:$/ {inIP=1;inTCP=0;inUDP=0} /^tcp:$/ {inIP=0;inTCP=1;inUDP=0} /^udp:$/ {inIP=0;inTCP=0;inUDP=1} {if (NF==1 && $1 !~ /^ip:$|^udp:$|^tcp:$/) inIP=inTCP=inUDP=0}'
# shellcheck disable=SC2016
@ -77,5 +79,5 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
fi
assertHaveCommand "$CMD"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FIGURE_SECTION $COMMON $SECTION_IP $SECTION_TCP $SECTION_UDP $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $FIGURE_SECTION $COMMON $SECTION_IP $SECTION_TCP $SECTION_UDP $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$HEADERIZE $FIGURE_SECTION $COMMON $SECTION_IP $SECTION_TCP $SECTION_UDP $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -6,7 +6,7 @@
. "$(dirname "$0")"/common.sh
# shellcheck disable=SC2166
if [ "$KERNEL" = "Linux" -o "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" ] ; then
if [ "$KERNEL" = "Linux" -o "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" -o "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand ps
CMD='ps auxww'
elif [ "$KERNEL" = "AIX" ] ; then

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -7,16 +8,16 @@
. "$(dirname "$0")"/common.sh
# shellcheck disable=SC2166
if [ "$KERNEL" = "Linux" -o "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" ] ; then
if [ "$KERNEL" = "Linux" -o "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" -o "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand ps
CMD='ps auxww'
if [ "$KERNEL" = "Linux" ] ; then
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1) -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}') -v IPv6_Address=$(ip -6 -brief address show scope global | xargs | cut -d ' ' -f 3 | cut -d '/' -f 1)"
fi
elif [ "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" ] ; then
elif [ "$KERNEL" = "Darwin" -o "$KERNEL" = "FreeBSD" -o "$KERNEL" = "OpenBSD" ] ; then
# Filters have been applied to get rid of IPv6 addresses designated for special usage to extract only the global IPv6 address.
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1) -v IPv6_Address=$(ifconfig -a | grep inet6 | grep -v ' ::1 ' | grep -v ' ::1/' | grep -v ' ::1%' | grep -v ' fe80::' | grep -v ' 2002::' | grep -v ' ff00::' | head -n 1 | xargs | cut -d '/' -f 1 | cut -d '%' -f 1 | cut -d ' ' -f 2)"
fi

View file

@ -1,4 +1,5 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
#
@ -7,10 +8,16 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
OLD_SEEK_FILE=$SPLUNK_HOME/var/run/splunk/unix_audit_seekfile # For handling upgrade scenarios
if [ -n "$SPLUNK_DB" ]; then
OLD_SEEK_FILE=$SPLUNK_HOME/var/run/splunk/unix_audit_seekfile # For handling upgrade scenarios
SEEK_FILE=$SPLUNK_HOME/var/run/splunk/unix_audit_seektime
else
# handle the case where this is not being run by the Splunk user from Splunk
OLD_SEEK_FILE=$HOME/.splunk_unix_audit_seekfile # For handling upgrade scenarios
SEEK_FILE=$HOME/.splunk_unix_audit_seektime
fi
CURRENT_AUDIT_FILE=/var/log/audit/audit.log # For handling upgrade scenarios
SEEK_FILE=$SPLUNK_HOME/var/run/splunk/unix_audit_seektime
TMP_ERROR_FILTER_FILE=$SPLUNK_HOME/var/run/splunk/unix_rlog_error_tmpfile # For filering out "no matches" error from stderr
TMP_ERROR_FILTER_FILE=$(mktemp) # For filering out "no matches" error from stderr
AUDIT_FILE="/var/log/audit/audit.log*"
if [ "$KERNEL" = "Linux" ] ; then
@ -56,6 +63,8 @@ elif [ "$KERNEL" = "Darwin" ] ; then
:
elif [ "$KERNEL" = "HP-UX" ] ; then
:
elif [ "$KERNEL" = "OpenBSD" ] ; then
:
elif [ "$KERNEL" = "FreeBSD" ] ; then
:
fi

View file

@ -1,11 +1,12 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
TMP_ERROR_FILTER_FILE=$SPLUNK_HOME/var/run/splunk/unix_selinux_error_tmpfile # For filtering out awk warning from stderr
TMP_ERROR_FILTER_FILE=$(mktemp) # For filtering out awk warning from stderr
PRINTF='END {printf "%s app=selinux %s %s %s %s\n", DATE, FILEHASH, SELINUX, SELINUXTYPE, SETLOCALDEFS}'
if [ "$KERNEL" = "Linux" ] ; then

View file

@ -128,9 +128,18 @@ elif [ "$KERNEL" = "Darwin" ] ; then
CMD='eval date ; ls -1 /System/Library/StartupItems/ /Library/StartupItems/'
# Get per-user startup items
# shellcheck disable=SC2044
for PLIST_FILE in $(find /Users -name "loginwindow.plist") ; do
CMD=$CMD' ; echo '$PLIST_FILE': ; defaults read '$PLIST_FILE
done
# For this to work properly when run as non-root, add a line to
# an /etc/sudoers.d file (eg - /etc/sudoers.d/splunk) like this:
# splunk ALL=(root) NOPASSWD: /usr/bin/find /Users -name loginwindow.plist
if [ $(id -u) != 0 ]; then
for PLIST_FILE in $(sudo -n /usr/bin/find /Users -name loginwindow.plist) ; do
CMD=$CMD' ; echo '$PLIST_FILE': ; defaults read '$PLIST_FILE
done
else
for PLIST_FILE in $(/usr/bin/find /Users -name loginwindow.plist) ; do
CMD=$CMD' ; echo '$PLIST_FILE': ; defaults read '$PLIST_FILE
done
fi
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0}'
# Retrieve path for system startup items
@ -187,6 +196,33 @@ elif [ "$KERNEL" = "Darwin" ] ; then
POSTPROCESS='END { if (SPLUNKD==0) { printf "%s app=\"Splunk\" StartMode=Disabled\n", DATE } }'
elif [ "$KERNEL" = "OpenBSD" ] ; then
# For this to work when running as a non-root user, add the following
# to /etc/doas.conf (replacing USERNAME with the user running the script):
# permit nopass USERNAME cmd /usr/sbin/rcctl args ls started
# permit nopass USERNAME cmd /usr/sbin/rcctl args ls failed
# permit nopass USERNAME cmd /usr/sbin/rcctl args ls rogue
if [ $(id -u) != 0 ]; then
failed=" $(doas -n /usr/sbin/rcctl ls failed) "
rogue=" $(doas -n /usr/sbin/rcctl ls rogue) "
running=" $(doas -n /usr/sbin/rcctl ls started) "
else
failed=" $(/usr/sbin/rcctl ls failed) "
rogue=" $(/usr/sbin/rcctl ls rogue) "
running=" $(/usr/sbin/rcctl ls started) "
fi
enabled=" $(/usr/sbin/rcctl ls on) "
for svc in $(/usr/sbin/rcctl ls all); do
enabled=false
echo $enabled | grep " $svc " && enabled=true
failed=false
echo $enabled | grep " $svc " && failed=true
rogue=false
echo $enabled | grep " $svc " && rogue=true
state=stopped
echo $enabled | grep " $svc " && state=running
date "+%a %b %e %H:%M:%S %Z %Y type=rcctl app=$svc, enabled=$enabled, failed=$failed, rogue=$rogue, running=$running"
done
else
# Exits
failUnsupportedScript

View file

@ -1,4 +1,5 @@
#!/usr/bin/env bash
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -237,7 +238,7 @@ function show_inputs
script_list=$(get_script_list)
for line in $script_list; do
case "$line" in
*unix* | *Splunk_TA_nix* ) get_scripted_input_status "$line"; input_counter=`expr $input_counter + 1`;
*unix* | *TA-unix* ) get_scripted_input_status "$line"; input_counter=`expr $input_counter + 1`;
esac
done
echo ""
@ -267,7 +268,7 @@ function enable_all_inputs
fi
if [ "$res" == "success" ] && [[ ( $line != *"_metric"* || $flag == 1 ) ]]; then
case "$line" in
*unix* | *Splunk_TA_nix* ) echo "enabling $line"; input_endpoint=$(build_scripted_input_endpoint "$line"); enable_scripted_input $input_endpoint;;
*unix* | *TA-unix* ) echo "enabling $line"; input_endpoint=$(build_scripted_input_endpoint "$line"); enable_scripted_input $input_endpoint;;
esac
fi
done
@ -289,7 +290,7 @@ function disable_all_inputs
script_list=$(get_script_list)
for line in $script_list; do
case "$line" in
*unix* | *Splunk_TA_nix* ) echo "disabling $line"; input_endpoint=$(build_scripted_input_endpoint "$line"); disable_scripted_input $input_endpoint;;
*unix* | *TA-unix* ) echo "disabling $line"; input_endpoint=$(build_scripted_input_endpoint "$line"); disable_scripted_input $input_endpoint;;
esac
done
for line in $MONITOR_INPUTS; do
@ -388,7 +389,7 @@ function clone_all_inputs
script_list=$(get_script_list)
for line in $script_list; do
case "$line" in
*unix* | *Splunk_TA_nix* ) echo ""; echo " cloning $line to $server_name"; echo ""; scripted_clone "$line"
*unix* | *TA-unix* ) echo ""; echo " cloning $line to $server_name"; echo ""; scripted_clone "$line"
esac
done
for line in $MONITOR_INPUTS; do
@ -642,7 +643,7 @@ function select_input_menu
script_list=$(get_script_list)
for line in $script_list; do
case "$line" in
*unix* | *Splunk_TA_nix* ) echo " $input_counter - $line"; selection_list[$input_counter]=$line; input_counter=`expr $input_counter + 1`;
*unix* | *TA-unix* ) echo " $input_counter - $line"; selection_list[$input_counter]=$line; input_counter=`expr $input_counter + 1`;
esac
done
for line in $MONITOR_INPUTS; do
@ -882,7 +883,7 @@ function set_unix_app_info
for line in $app_output; do
case "$line" in
*unix* ) set_app_installed "unix";;
*Splunk_TA_nix* ) set_app_installed "Splunk_TA_nix";;
*TA-unix* ) set_app_installed "TA-unix";;
*ENABLED*) set_app_enabled;;
#*DISABLED*) set_app_disabled;;
esac

View file

@ -1,3 +1,4 @@
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
@ -20,19 +21,19 @@ class SetupService(splunk.rest.BaseRestHandler):
sessionKey = self.sessionKey
try:
conf = bundle.getConf(
"app", sessionKey, namespace="Splunk_TA_nix", owner="nobody"
"app", sessionKey, namespace="TA-unix", owner="nobody"
)
stanza = conf.stanzas["install"].findKeys("is_configured")
if stanza:
if stanza["is_configured"] == "0" or stanza["is_configured"] == "false":
conf["install"]["is_configured"] = "true"
splunk.rest.simpleRequest(
"/apps/local/Splunk_TA_nix/_reload", sessionKey=sessionKey
"/apps/local/TA-unix/_reload", sessionKey=sessionKey
)
else:
conf["install"]["is_configured"] = "true"
splunk.rest.simpleRequest(
"/apps/local/Splunk_TA_nix/_reload", sessionKey=sessionKey
"/apps/local/TA-unix/_reload", sessionKey=sessionKey
)
except Exception as e:
self.response.write(e)

View file

@ -6,8 +6,9 @@
. "$(dirname "$0")"/common.sh
SSH_CONFIG_FILE=""
if [ "$KERNEL" = "Linux" ] || [ "$KERNEL" = "SunOS" ] ; then
if [ "$KERNEL" = "Linux" ] || [ "$KERNEL" = "SunOS" ] || [ "$KERNEL" = "OpenBSD" ] ; then
SSH_CONFIG_FILE=/etc/ssh/sshd_config
[ "$KERNEL" = "OpenBSD" ] && SPLUNK_HOME=/usr
elif [ "$KERNEL" = "Darwin" ] ; then
SSH_CONFIG_FILE=/etc/sshd_config
else

View file

@ -51,6 +51,8 @@ elif [ "$KERNEL" = "Darwin" ] && [ $FOUND_SNTP -eq 0 ] ; then # Mac OS 10.14.6 o
echo "CONFIG=$CONFIG, SERVER=$SERVER" >> "$TEE_DEST"
#With Chrony
elif [ "$KERNEL" = "OpenBSD" ]; then
CMD2="ntpctl -s all"
else
CMD2="chronyc -n sources"
fi
@ -60,8 +62,29 @@ CMD1='date'
assertHaveCommand $CMD1
assertHaveCommand "$CMD2"
$CMD1 | tee -a "$TEE_DEST"
echo "Cmd1 = [$CMD1]" >> "$TEE_DEST"
$CMD1 | tee -a "$TEE_DEST"
$CMD2 | tee -a "$TEE_DEST"
echo "Cmd2 = [$CMD2]" >> "$TEE_DEST"
if [ "$KERNEL" = "Darwin" ] && [ $FOUND_SNTP -eq 0 ] ; then
TMP_ERROR_FILTER_FILE=$SPLUNK_HOME/var/run/splunk/unix_time_error_tmpfile
OUTPUT=$($CMD2 2>$TMP_ERROR_FILTER_FILE)
if grep -q "Timeout" < $TMP_ERROR_FILTER_FILE; then
LAST_LINE=$(echo "$OUTPUT" | tail -n 1)
if [[ "$LAST_LINE" == *"$SERVER"* ]]; then
echo "$LAST_LINE" | tee -a "$TEE_DEST"
fi
cat $TMP_ERROR_FILTER_FILE >> $TEE_DEST
echo "$OUTPUT" >> "$TEE_DEST"
rm $TMP_ERROR_FILTER_FILE 2>/dev/null
elif grep -vq "Timeout" < $TMP_ERROR_FILTER_FILE; then
cat $TMP_ERROR_FILTER_FILE >&2
echo "$OUTPUT" >> "$TEE_DEST"
rm $TMP_ERROR_FILTER_FILE 2>/dev/null
else
echo "$OUTPUT" | tee -a "$TEE_DEST"
fi
else
$CMD2 | tee -a "$TEE_DEST"
fi

View file

@ -1,22 +1,30 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
TMP_ERROR_FILTER_FILE=$SPLUNK_HOME/var/run/splunk/unix_update_error_tmpfile # For filering out apt warning from stderr
TMP_ERROR_FILTER_FILE=$(mktemp) # For filering out apt warning from stderr
if [ "$KERNEL" = "Linux" ] ; then
assertHaveCommand date
OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2)
OS_FILE=/etc/os-release
# Ubuntu doesn't have yum installed by default hence apt is being used to get the list of upgradable packages
if [ "$OSName" = "Ubuntu" ]; then
if [ "$OSName" = "Ubuntu" ] || [ "$OSName" = "Debian_GNU/Linux" ]; then
assertHaveCommand apt
assertHaveCommand sed
# For this to work properly, add a line to /etc/sudoers like this:
# splunk ALL=(root) NOPASSWD: /usr/bin/apt update
# Without the above line, 'apt list --upgradable' will not show updated packages unless the package databases were updated outside of this script
# sed command here replaces '/, [, ]' with ' '
CMD='eval date ; eval apt list --upgradable | sed "s/\// /; s/\[/ /; s/\]/ /"'
if [ $(id -u) != 0 ]; then
CMD='eval date ; sudo -n /usr/bin/apt update > /dev/null 2>&1 ; eval apt list --upgradable | sed "s/\// /; s/\[/ /; s/\]/ /"'
else
CMD='eval date ; /usr/bin/apt update > /dev/null 2>&1 ; eval apt list --upgradable | sed "s/\// /; s/\[/ /; s/\]/ /"'
fi
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0}'
# shellcheck disable=SC2016
@ -33,6 +41,22 @@ if [ "$KERNEL" = "Linux" ] ; then
# shellcheck disable=SC2016
PARSE_2='header_found { gsub(/[[:space:]]*\|[[:space:]]*/, "|"); split($0, arr, /\|/); printf "%s repository=%s package=%s current_package_version=%s latest_package_version=%s sles_architecture=%s\n", DATE, arr[2], arr[3], arr[4], arr[5], arr[6]}'
MESSAGE="$PARSE_0 $PARSE_1 $PARSE_2"
elif [ "$OSName" = "Arch_Linux" ] || [ "$OSName" = "Arch_Linux_ARM" ]; then
assertHaveCommand checkupdates
assertHaveCommand sed
# For this to work properly, add a line to /etc/sudoers like this:
# splunk ALL=(root) NOPASSWD: /usr/bin/pacman -Syy
# Without the above line, checkupdates will not show updated packages unless the package databases were updated outside of this script (similar to Debian's apt update)
if [ $(id -u) != 0 ]; then
CMD='eval date ; eval uname -m | sed -r "s/(armv7l|aarch64)/arm64/;s/x86_64/amd64/"; sudo -n /usr/bin/pacman -Syy > /dev/null 2>&1 ; eval checkupdates'
else
CMD='eval date ; eval uname -m | sed -r "s/(armv7l|aarch64)/arm64/;s/x86_64/amd64/"; /usr/bin/pacman -Syy > /dev/null 2>&1 ; eval checkupdates'
fi
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0}'
PARSE_1='NR==2 {ARCH=$0}'
PARSE_2='NR>2 {printf "%s arch_architecture=%s package=%s current_package_version=%s latest_package_version=%s\n", DATE, ARCH, $1, $2, $4}'
MESSAGE="$PARSE_0 $PARSE_1 $PARSE_2"
else
assertHaveCommand yum
@ -79,7 +103,7 @@ elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand date
assertHaveCommand softwareupdate
CMD='eval date ; softwareupdate -l'
CMD='eval date ; softwareupdate -l 2>&1 | grep -v "XType: Using static font registry"'
# shellcheck disable=SC2016
PARSE_0='NR==1 {
DATE=$0
@ -91,15 +115,21 @@ elif [ "$KERNEL" = "Darwin" ] ; then
# of the update. Otherwise, print the update.
# shellcheck disable=SC2016
PARSE_1='NR>1 && PROCESS==1 && $0 !~ /^[[:blank:]]*$/ {
if ( $0 ~ /^[[:blank:]]*\*/ ) {
PACKAGE="package=\"" $2 "\""
if ( $1 == "Title:" ) {
line = $0;
gsub(/^.*Title: /, "", line);
gsub(/, Version:.*$/, "", line);
PACKAGE="package=\"" line "\""
version = $0;
gsub(/^.*Title: [^,]+, Version: /, "", version);
gsub(/, Size:.*$/, "", version);
VERSION="latest_package_version=\"" version "\""
RECOMMENDED=""
RESTART=""
TOTAL=TOTAL+1
} else {
if ( $0 ~ /recommended/ ) { RECOMMENDED="is_recommended=\"true\"" }
if ( $0 ~ /restart/ ) { RESTART="restart_required=\"true\"" }
printf "%s %s %s %s\n", DATE, PACKAGE, RECOMMENDED, RESTART
if ( $0 ~ /Recommended: YES/ ) { RECOMMENDED="is_recommended=\"true\"" }
if ( $0 ~ /Action: restart/ ) { RESTART="restart_required=\"true\"" }
printf "%s %s %s %s\n", DATE, PACKAGE, VERSION, RECOMMENDED, RESTART
}
}'
@ -115,6 +145,10 @@ elif [ "$KERNEL" = "Darwin" ] ; then
MESSAGE="$PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3"
elif [ "$KERNEL" = "OpenBSD" ] ; then
CMD="eval pkg_add -usv 2>&1 | grep -vE '(Adding quirks-|pkg_add should be run as root)' | grep ^Adding | sed -E 's/^Adding ([^:]+:)?(.*)->(.*)\(pretending\)/\2 \3/' | while read pkg ver; do name=\$(pkg_info -P \$pkg | grep -A1 ^Pkgpath:|tail -n1|cut -d/ -f2-); date \"+%a %b %e %H:%M:%S %Z %Y arch_architecture=\$(arch -s) package=\$name current_package_version=\$(echo \$pkg | sed -E \"s/\$name-//\") latest_package_version=\$ver\"; done"
#CMD="eval for f in \$(pkg_add -usv 2>&1 | grep -vE \"(Adding quirks-|pkg_add should be run as root)\" | grep ^Adding | sed -E \"s/^Adding ([^:]+:)?(.*)->(.*)\(pretending\)/\2 \3/\"); do echo \$f; done"
MESSAGE="{print}"
else
# Exits
failUnsupportedScript

View file

@ -18,7 +18,7 @@ fi
# This should work for any POSIX-compliant system, but in case it doesn't
# we have left the individual OS names here to be broken out later on.
if [ "$KERNEL" = "Linux" ] || [ "$KERNEL" = "SunOS" ] || [ "$KERNEL" = "AIX" ] || [ "$KERNEL" = "HP-UX" ] || [ "$KERNEL" = "Darwin" ] || [ "$KERNEL" = "FreeBSD" ] ; then
if [ "$KERNEL" = "Linux" ] || [ "$KERNEL" = "SunOS" ] || [ "$KERNEL" = "AIX" ] || [ "$KERNEL" = "HP-UX" ] || [ "$KERNEL" = "Darwin" ] || [ "$KERNEL" = "FreeBSD" ] || [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand date
assertHaveCommand ps
CMD='eval date; LC_ALL=POSIX ps -o etime= -p 1'

View file

@ -5,13 +5,31 @@
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
PRINTF='END {printf "%s %s %s %s %s %s\n", DATE, MACH_HW_NAME, MACH_ARCH_NAME, OS_REL, OS_NAME, OS_VER}'
PRINTF='END {printf "%s %s %s %s %s %s %s %s %s\n", DATE, MACH_HW_NAME, MACH_ARCH_NAME, OS_REL, OS_NAME, OS_VER, KERNEL_NAME, KERNEL_VERSION, KERNEL_RELEASE}'
if [ "$KERNEL" = "Linux" ] || [ "$KERNEL" = "SunOS" ] || [ "$KERNEL" = "Darwin" ] || [ "$KERNEL" = "FreeBSD" ] ; then
if [ "$KERNEL" = "Linux" ] ; then
assertHaveCommand date
assertHaveCommand uname
CMD='eval date ; eval uname -m ; eval uname -r ; eval uname -s ; eval uname -v ; eval uname -p'
VERSION=$(grep "^VERSION=" /etc/*-release | cut -d= -f2 | sed 's/^["]*//;s/["]*$//' | paste -sd " " -)
NAME=$(grep "^NAME=" /etc/*-release | cut -d= -f2 | sed 's/^["]*//;s/["]*$//' | paste -sd " " -)
VERSION_ID=$(grep "^VERSION_ID=" /etc/*-release | cut -d= -f2 | sed 's/^["]*//;s/["]*$//' | paste -sd " " -)
MACHINE_ARCH=$(uname -p)
which dpkg > /dev/null 2>&1 && MACHINE_ARCH=$(dpkg --print-architecture)
which pacman > /dev/null 2>&1 && MACHINE_ARCH=$(uname -m | sed -r "s/(armv7l|aarch64)/arm64/;s/x86_64/amd64/") && VERSION=rolling && VERSION_ID=rolling
CMD="eval date ; eval uname -m ; echo \"$VERSION\" ; echo \"$NAME\" ; echo \"$VERSION_ID\" ; echo \"$MACHINE_ARCH\" ; eval uname -s ; eval uname -v ; eval uname -r"
elif [ "$KERNEL" = "SunOS" ] || [ "$KERNEL" = "FreeBSD" ] || [ "$KERNEL" = "OpenBSD" ] ; then
assertHaveCommand date
assertHaveCommand uname
CMD='eval date ; eval uname -m ; eval uname -r ; echo $KERNEL ; eval uname -r; eval uname -p ; eval uname -s ; eval uname -v ; eval uname -r;'
elif [ "$KERNEL" = "Darwin" ] ; then
# Darwin-macos uses sw_vers for os version, name and release switch.
assertHaveCommand date
assertHaveCommand uname
VERSION=$(sw_vers -BuildVersion)
NAME=$(sw_vers -productName)
VERSION_ID=$(sw_vers -ProductVersion)
CMD="eval date ; eval uname -m ; echo \"$VERSION_ID ($VERSION)\" ; echo \"$NAME\" ; echo \"$VERSION_ID\" ; eval uname -p ; eval uname -s ; eval uname -v ; eval uname -r"
elif [ "$KERNEL" = "HP-UX" ] ; then
# HP-UX lacks -p switch.
assertHaveCommand date
@ -21,7 +39,7 @@ elif [ "$KERNEL" = "AIX" ] ; then
# AIX uses oslevel for version and release switch.
assertHaveCommand date
assertHaveCommand uname
CMD='eval date ; eval uname -m ; eval oslevel -r ; eval uname -s ; eval oslevel -s'
CMD='eval date ; eval uname -m ; eval oslevel -r ; eval uname -s ; eval oslevel ; eval uname -m ; eval uname -s ; eval uname -v; eval uname -r'
fi
# Get the date.
@ -37,8 +55,14 @@ PARSE_3='NR==4 {OS_NAME="os_name=\"" $0 "\""}'
PARSE_4='NR==5 {OS_VER="os_version=\"" $0 "\""}'
# shellcheck disable=SC2016
PARSE_5='NR==6 {MACH_ARCH_NAME="machine_architecture_name=\"" $0 "\""}'
# shellcheck disable=SC2016
PARSE_6='NR==7 {KERNEL_NAME="kernel_name=\"" $0 "\""}'
# shellcheck disable=SC2016
PARSE_7='NR==8 {KERNEL_VERSION="kernel_version=\"" $0 "\""}'
# shellcheck disable=SC2016
PARSE_8='NR==9 {KERNEL_RELEASE="kernel_release=\"" $0 "\""}'
MASSAGE="$PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5"
MASSAGE="$PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5 $PARSE_6 $PARSE_7 $PARSE_8"
$CMD | tee "$TEE_DEST" | $AWK "$MASSAGE $PRINTF"
echo "Cmd = [$CMD]; | $AWK '$MASSAGE $PRINTF'" >> "$TEE_DEST"

View file

@ -1,10 +1,13 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
# hardware.sh is called in all commands to get CPU counts. The CPU count is required to determine
# the number of threads that waited for execution time. CPU count accounts for hyperthreaded cores so
# (load average - CPU count) gives a reasonable estimate of how many threads were waiting to execute.
@ -26,7 +29,7 @@ if [ "$KERNEL" = "Linux" ] ; then
# shellcheck disable=SC2016
PARSE_1='/total memory$/ {memTotalMB=$1/1024} /free memory$/ {memFreeMB+=$1/1024} /buffer memory$/ {memFreeMB+=$1/1024} /swap cache$/ {memFreeMB+=$1/1024}'
# shellcheck disable=SC2016
PARSE_2='/pages paged out$/ {pgPageOut=$1} /used swap$/ {swapUsed=$1} /free swap$/ {swapFree=$1} /pages swapped out$/ {pgSwapOut=$1}'
PARSE_2='/(K|pages) paged out$/ {pgPageOut=$1} /used swap$/ {swapUsed=$1} /free swap$/ {swapFree=$1} /pages swapped out$/ {pgSwapOut=$1}'
# shellcheck disable=SC2016
PARSE_3='/interrupts$/ {interrupts=$1} /CPU context switches$/ {cSwitches=$1} /forks$/ {forks=$1}'
# shellcheck disable=SC2016
@ -126,9 +129,9 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand sysctl
assertHaveCommand top
assertHaveCommand sar
assertHaveCommand vm_stat
# shellcheck disable=SC2016
CMD='eval sysctl hw.memsize ; sysctl vm.swapusage ; top -l 1 -n 0; `dirname $0`/hardware.sh; sar -gp 1 2'
CMD='eval sysctl hw.memsize ; sysctl vm.swapusage ; top -l 1 -n 0; `dirname $0`/hardware.sh; vm_stat | awk "/Pageouts:/{print \"pgpageout \" \$NF}/^Swapouts:/{print \"pgswapout \" \$NF}"; vm_stat -c5 1 | tail -n -4 | awk "{pi=pi+\$19;po=po+\$20;si=si+\$21;so=so+\$22}END{printf \"pginps %.2f pgoutps %.2f swinps %.2f swoups %.2f\n\",pi/4,po/4,si/4,so/4}"'
FUNCS='function toMB(s) {n=0+s; if (index(s,"K")) {n /= 1024} if (index(s,"G")) {n *= 1024} return n}'
# shellcheck disable=SC2016
PARSE_0='/^hw.memsize:/ {memTotalMB=$2 / (1024*1024)}'
@ -137,24 +140,39 @@ elif [ "$KERNEL" = "Darwin" ] ; then
# shellcheck disable=SC2016
PARSE_2='/^vm.swapusage:/ {swapUsed=toMB($7); swapFree=toMB($10)}'
# shellcheck disable=SC2016
PARSE_3='/^VM:/ {pgPageOut=0+$7}'
if $OSX_GE_SNOW_LEOPARD; then
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-1)}'
else
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-2)}'
fi
PARSE_3='/^pgpageout / {pgPageOut=0+$2}'
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-1)}'
# shellcheck disable=SC2016
PARSE_5='/^Load Avg:/ {loadAvg1mi=0+$3}'
# shellcheck disable=SC2016
PARSE_6='/^CPU_COUNT/ {cpuCount=$2}'
# shellcheck disable=SC2016
PARSE_7='($0 ~ "Average" && $1 ~ "pgout*") {next} {pgPageOut_PS=$2}'
PARSE_7='$1 == "pginps" {pgPageIn_PS=$2;pgPageOut_PS=$4;pgSwapIn=$6;pgSwapOut=$8}'
# shellcheck disable=SC2016
PARSE_8='($0 ~ "Average" && $1 ~ "pgin*") {next} {pgPageIn_PS=$2}'
PARSE_8='/^pgswapout / {pgSwapOut=0+$2}'
MASSAGE="$FUNCS $PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5 $PARSE_6 $PARSE_7 $PARSE_8 $DERIVE"
FILL_BLANKS='END {pgSwapOut=cSwitches=interrupts=interrupts_PS=forks="?"}'
FILL_BLANKS='END {cSwitches=interrupts=interrupts_PS=forks="0"}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
# shellcheck disable=SC2016
CMD='eval sysctl -n hw.physmem ; vmstat -s ; top -Sb 0; `dirname $0`/hardware.sh'
FUNCS='function toMB(s) {n=0+s; if (index(s,"K")) {n /= 1024} if (index(s,"G")) {n *= 1024} return n}'
# shellcheck disable=SC2016
PARSE_0='(NR==1) {memTotalMB=$1 / (1024*1024)}'
# shellcheck disable=SC2016
PARSE_1='/pages being paged out$/ {pgPageOut+=$1} /forks$/ {forks+=$1} /cpu context switches$/ {cSwitches+=$1} /interrupts$/ {interrupts+=$1}'
# shellcheck disable=SC2016
PARSE_2='/load averages:/ {loadAvg1mi=$3} /^[0-9]+ processes: / {processes=$1}'
# shellcheck disable=SC2016
PARSE_3='/Swap: / { split($10, a, "/"); swapTotal=toMB(a[2]); swapUsed=toMB(a[1]); swapFree=swapTotal-swapFree; } /^Memory: / {memFreeMB=toMB($6)}'
# shellcheck disable=SC2016
PARSE_4='/^CPU_COUNT/ {cpuCount=$2}'
# shellcheck disable=SC2016
PARSE_5='($3 ~ "INTR") {nr1[NR+3]} NR in nr1 {interrupts_PS=$3}'
# shellcheck disable=SC2016
PARSE_6='($3 ~ "pgpgin*") {nr2[NR+3]} NR in nr2 {pgPageIn_PS=$3; pgPageOut_PS=$4}'
MASSAGE="$FUNCS $PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5 $PARSE_6 $DERIVE"
FILL_BLANKS='END {threads=pgSwapOut="?"}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
# shellcheck disable=SC2016
CMD='eval sysctl hw.physmem ; vmstat -s ; top -Sb 0; `dirname $0`/hardware.sh'
@ -177,5 +195,5 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
FILL_BLANKS='END {threads=pgSwapOut="?"}'
fi
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $MASSAGE $FILL_BLANKS $PRINTF" header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK "$HEADERIZE $MASSAGE $FILL_BLANKS $PRINTF" header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK '$HEADERIZE $MASSAGE $FILL_BLANKS $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -1,10 +1,13 @@
#!/bin/sh
# Copyright (C) 2025 Michael Erdely All Rights Reserved.
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
assertHaveCommand column
# hardware.sh is called in all commands to get CPU counts. The CPU count is required to determine
# the number of threads that waited for execution time. CPU count accounts for hyperthreaded cores so
# (load average - CPU count) gives a reasonable estimate of how many threads were waiting to execute.
@ -23,16 +26,16 @@ if [ "$KERNEL" = "Linux" ] ; then
# shellcheck disable=SC2016
CMD='eval uptime ; ps -e | wc -l ; ps -eT | wc -l ; vmstat -s ; `dirname $0`/hardware.sh; sar -B 1 2; sar -I SUM 1 2'
if [ ! -f "/etc/os-release" ] ; then
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | head -n 1| awk -F" release " '{print $1}'| tr ' ' '_') -v OS_version=$(cat /etc/*release | head -n 1| awk -F" release " '{print $2}' | cut -d\. -f1) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
else
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep '\bVERSION_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(hostname -I | cut -d\ -f1)"
DEFINE="-v OSName=$(cat /etc/*release | grep '\bNAME=' | cut -d '=' -f2 | tr ' ' '_' | cut -d\" -f2) -v OS_version=$(cat /etc/*release | grep -E '\b(VERSION|BUILD)_ID=' | cut -d '=' -f2 | cut -d\" -f2) -v IP_address=$(ip -4 route show default | awk '{print $9}')"
fi
# shellcheck disable=SC2016
PARSE_0='NR==1 {loadAvg1mi=0+$(NF-2)} NR==2 {processes=$1} NR==3 {threads=$1}'
# shellcheck disable=SC2016
PARSE_1='/total memory$/ {memTotalMB=$1/1024} /free memory$/ {memFreeMB+=$1/1024} /buffer memory$/ {memFreeMB+=$1/1024} /swap cache$/ {memFreeMB+=$1/1024}'
# shellcheck disable=SC2016
PARSE_2='/pages paged out$/ {pgPageOut=$1} /used swap$/ {swapUsed=$1} /free swap$/ {swapFree=$1} /pages swapped out$/ {pgSwapOut=$1}'
PARSE_2='/(K|pages) paged out$/ {pgPageOut=$1} /used swap$/ {swapUsed=$1} /free swap$/ {swapFree=$1} /pages swapped out$/ {pgSwapOut=$1}'
# shellcheck disable=SC2016
PARSE_3='/interrupts$/ {interrupts=$1} /CPU context switches$/ {cSwitches=$1} /forks$/ {forks=$1}'
# shellcheck disable=SC2016
@ -136,9 +139,9 @@ elif [ "$KERNEL" = "HP-UX" ] ; then
elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand sysctl
assertHaveCommand top
assertHaveCommand sar
assertHaveCommand vm_stat
# shellcheck disable=SC2016
CMD='eval sysctl hw.memsize ; sysctl vm.swapusage ; top -l 1 -n 0; `dirname $0`/hardware.sh; sar -gp 1 2'
CMD='eval sysctl hw.memsize ; sysctl vm.swapusage ; top -l 1 -n 0; `dirname $0`/hardware.sh; vm_stat | awk "/Pageouts:/{print \"pgpageout \" \$NF}/^Swapouts:/{print \"pgswapout \" \$NF}"; vm_stat -c5 1 | tail -n -4 | awk "{pi=pi+\$19;po=po+\$20;si=si+\$21;so=so+\$22}END{printf \"pginps %.2f pgoutps %.2f swinps %.2f swoups %.2f\n\",pi/4,po/4,si/4,so/4}"'
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1)"
FUNCS='function toMB(s) {n=0+s; if (index(s,"K")) {n /= 1024} if (index(s,"G")) {n *= 1024} return n}'
# shellcheck disable=SC2016
@ -148,24 +151,40 @@ elif [ "$KERNEL" = "Darwin" ] ; then
# shellcheck disable=SC2016
PARSE_2='/^vm.swapusage:/ {swapUsed=toMB($7); swapFree=toMB($10)}'
# shellcheck disable=SC2016
PARSE_3='/^VM:/ {pgPageOut=0+$7}'
if $OSX_GE_SNOW_LEOPARD; then
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-1)}'
else
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-2)}'
fi
PARSE_3='/^pgpageout / {pgPageOut=0+$2}'
# shellcheck disable=SC2016
PARSE_4='/^Processes:/ {processes=$2; threads=$(NF-1)}'
# shellcheck disable=SC2016
PARSE_5='/^Load Avg:/ {loadAvg1mi=0+$3}'
# shellcheck disable=SC2016
PARSE_6='/^CPU_COUNT/ {cpuCount=$2}'
# shellcheck disable=SC2016
PARSE_7='($0 ~ "Average" && $1 ~ "pgout*") {next} {pgPageOut_PS=$2}'
PARSE_7='$1 == "pginps" {pgPageIn_PS=$2;pgPageOut_PS=$4;pgSwapIn=$6;pgSwapOut=$8}'
# shellcheck disable=SC2016
PARSE_8='($0 ~ "Average" && $1 ~ "pgin*") {next} {pgPageIn_PS=$2}'
PARSE_8='/^pgswapout / {pgSwapOut=0+$2}'
MESSAGE="$FUNCS $PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5 $PARSE_6 $PARSE_7 $PARSE_8 $DERIVE"
FILL_BLANKS='END {pgSwapOut=cSwitches=interrupts=interrupts_PS=forks="?"}'
FILL_BLANKS='END {cSwitches=interrupts=interrupts_PS=forks="0"}'
elif [ "$KERNEL" = "OpenBSD" ] ; then
# shellcheck disable=SC2016
CMD='eval sysctl -n hw.physmem ; vmstat -s ; top -Sb 0; `dirname $0`/hardware.sh'
DEFINE="-v OSName=$(uname -s) -v OS_version=$(uname -r) -v IP_address=$(ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -n 1)"
FUNCS='function toMB(s) {n=0+s; if (index(s,"K")) {n /= 1024} if (index(s,"G")) {n *= 1024} return n}'
# shellcheck disable=SC2016
PARSE_0='(NR==1) {memTotalMB=$1 / (1024*1024)}'
# shellcheck disable=SC2016
PARSE_1='/pages being paged out$/ {pgPageOut+=$1} /forks$/ {forks+=$1} /cpu context switches$/ {cSwitches+=$1} /interrupts$/ {interrupts+=$1}'
# shellcheck disable=SC2016
PARSE_2='/load averages:/ {loadAvg1mi=$3} /^[0-9]+ processes: / {processes=$1}'
# shellcheck disable=SC2016
PARSE_3='/Swap: / { split($10, a, "/"); swapTotal=toMB(a[2]); swapUsed=toMB(a[1]); swapFree=swapTotal-swapFree; } /^Memory: / {memFreeMB=toMB($6)}'
# shellcheck disable=SC2016
PARSE_4='/^CPU_COUNT/ {cpuCount=$2}'
# shellcheck disable=SC2016
PARSE_5='($3 ~ "INTR") {nr1[NR+3]} NR in nr1 {interrupts_PS=$3}'
# shellcheck disable=SC2016
PARSE_6='($3 ~ "pgpgin*") {nr2[NR+3]} NR in nr2 {pgPageIn_PS=$3; pgPageOut_PS=$4}'
MESSAGE="$FUNCS $PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $PARSE_5 $PARSE_6 $DERIVE"
FILL_BLANKS='END {threads=pgSwapOut="?"}'
elif [ "$KERNEL" = "FreeBSD" ] ; then
# shellcheck disable=SC2016
CMD='eval sysctl hw.physmem ; vmstat -s ; top -Sb 0; `dirname $0`/hardware.sh'
@ -189,5 +208,5 @@ elif [ "$KERNEL" = "FreeBSD" ] ; then
FILL_BLANKS='END {threads=pgSwapOut="?"}'
fi
# shellcheck disable=SC2086
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$HEADERIZE $MESSAGE $FILL_BLANKS $FILL_DIMENSIONS $PRINTF " header="$HEADER"
$CMD | tee "$TEE_DEST" | $AWK $DEFINE "$HEADERIZE $MESSAGE $FILL_BLANKS $FILL_DIMENSIONS $PRINTF " header="$HEADER" | column -t
echo "Cmd = [$CMD]; | $AWK $DEFINE '$HEADERIZE $MESSAGE $FILL_BLANKS $FILL_DIMENSIONS $PRINTF' header=\"$HEADER\"" >> "$TEE_DEST"

View file

@ -7,24 +7,24 @@
[install]
is_configured = false
state = enabled
build = 1720176219
build = 1738793362
[ui]
setup_view = ta_nix_configuration
is_visible = true
label = Splunk Add-on for Unix and Linux
label = Technical Add-on for Unix and Linux
docs_section_override = AddOns:released
[launcher]
author = Splunk, Inc.
version = 9.2.0
description = Splunk Add-on for Unix and Linux
author = Michael Erdely
version = 10.0.0.1
description = Technical Add-on for Unix and Linux
[package]
id = Splunk_TA_nix
check_for_updates = true
#[package]
#id = TA-unix
#check_for_updates = true
[id]
name = Splunk_TA_nix
version = 9.2.0
name = TA-unix
version = 10.0.0.1

View file

@ -4,11 +4,12 @@
-->
<dashboard script="setup_cloud.js" stylesheet="setup.css" version="1.1">
<label>Splunk Add-on for Unix and Linux: Setup</label>
<label>Technical Add-on for Unix and Linux: Setup</label>
<row>
<panel>
<html>
<p>Please set up this add-on on your forwarders. Documentation on how to configure this add-on is
<p>Please set up this add-on on your forwarders. Documentation on how to configure this add-on,
which is the same as the Splunk Add-on for Unix and Linux, is
<a target="_blank" href="http://docs.splunk.com/Documentation/UnixAddOn/latest/User/DeploytheSplunkAdd-onforUnixandLinuxinadistributedSplunkenvironment">here</a>.
<br/>
Click on below button, if you are getting redirected to this page while editing the add-on's knowledge object.

View file

@ -10,15 +10,15 @@
|| It has no effect on Splunk Enterprise.
-->
<dashboard script="setup.js" stylesheet="setup.css" isVisible="false" version="1.1">
<label>Splunk Add-on for Unix and Linux: Setup</label>
<label>Technical Add-on for Unix and Linux: Setup</label>
<row>
<html>
<p id="overview">
The Splunk Add-on for Unix and Linux provides pre-built data inputs to facilitate
The Technical Add-on for Unix and Linux provides pre-built data inputs to facilitate
Linux and Unix system monitoring using Splunk. Check out the
<a href="http://apps.splunk.com/app/833/" target="_blank">
Splunk for Unix Technical Add-on
</a> page on <a href="http://apps.splunk.com/" target="_blank">Splunkbase</a>
<a href="https://git.erdelynet.com/mike/TA-unix" target="_blank">
Technical Add-on for Unix and Linux
</a> page
for support information, the latest updates, and more.
</p>

View file

@ -8,7 +8,7 @@
search = NOT *
[nix_ta_data]
search = eventtype=nix_ta_custom_eventtype OR (sourcetype IN (vmstat_metric, iostat_metric, ps_metric, df_metric, interfaces_metric, cpu_metric, vmstat, iostat, ps, top, netstat, bandwidth, protocol, openPorts, time, lsof, df, who, usersWithLoginPrivs, lastlog, interfaces, cpu, auditd, package, hardware, bash_history, Unix:ListeningPorts, Unix:UserAccounts, Linux:SELinuxConfig, Unix:Service, Unix:SSHDConfig, Unix:Update, Unix:Uptime, Unix:Version, Unix:VSFTPDConfig, config_file, dhcpd, nfsiostat, ignored_type, aix_secure, osx_secure, linux_secure, linux_audit, syslog) OR source IN (/Library/Logs/*, /var/log/*, /var/adm/*, /etc/*))
search = eventtype=nix_ta_custom_eventtype OR (sourcetype IN (docker_metric, vmstat_metric, iostat_metric, ps_metric, df_metric, interfaces_metric, cpu_metric, docker, vmstat, iostat, ps, top, netstat, bandwidth, protocol, openPorts, time, lsof, df, who, usersWithLoginPrivs, lastlog, interfaces, cpu, auditd, package, hardware, bash_history, Unix:ListeningPorts, Unix:UserAccounts, Linux:SELinuxConfig, Unix:Service, Unix:SSHDConfig, Unix:Update, Unix:Uptime, Unix:Version, Unix:VSFTPDConfig, config_file, dhcpd, nfsiostat, ignored_type, aix_secure, osx_secure, linux_secure, linux_audit, syslog) OR source IN (/Library/Logs/*, /var/log/*, /var/adm/*, /etc/*))
###### Globals ######
[nix_security]
@ -112,6 +112,10 @@ search = sourcetype=time
[usersWithLoginPrivs]
search = sourcetype=usersWithLoginPrivs
[docker]
search = sourcetype=docker
#tags = performance os avail unix report docker
[vmstat]
search = sourcetype=vmstat
#tags = performance os avail unix report vmstat resource success memory
@ -229,12 +233,21 @@ search = eventtype=nix_ta_data "pam_rhosts_auth" AND ("denied to" OR "access not
search = eventtype=nix_ta_data "pam_rhosts_auth" AND "allowed to"
#tags = application authentication remote
## sshd-session
[sshd_session_start]
search = sourcetype=linux_secure eventtype=nix_ta_data ("sshd-session[" OR "sshd[") AND ("Failed password for" OR "Connection closed by invalid user" OR "Unable to negotiate" OR "session opened for user" OR "banner exchange" OR "Could not get shadow information" OR "Accepted password")
#tags = network session start
[sshd_session_end]
search = sourcetype=linux_secure eventtype=nix_ta_data ("sshd-session[" OR "sshd[") AND ("Read error from remote host" OR "Connection timed out" OR "Disconnected from user" OR "Connection closed by" OR "session closed for user") AND NOT "Connection closed by invalid user"
#tags = network session end
## sshd
[sshd_authentication]
# osx sshd authentication error
# Jul 16 11:10:45 mycomputer sshd[34666]: error: PAM: authentication error for xxx from localhost via ::1
# Apr 2 12:42:08 mycomputer sshd[15578]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost user=host
search = eventtype=nix_ta_data "sshd[" (((Accepted OR Failed OR failure OR "Invalid user" OR "authentication error") (from OR ())) OR "Authorized to" OR "Authentication tried" OR "Login restricted") NOT ("POSSIBLE BREAK-IN ATTEMPT")
search = eventtype=nix_ta_data "sshd[" (((Accepted OR Failed OR failure OR "Invalid user" OR "authentication error") (from OR ())) OR "Authorized to" OR "Authentication tried" OR "Login restricted") NOT ("POSSIBLE BREAK-IN ATTEMPT") AND NOT sourcetype=linux_secure
#tags = authentication remote
[ssh_login_postponed]
@ -242,7 +255,7 @@ search = eventtype=nix_ta_data punct="*_::_*_[]:____*_...___" sshd Postponed
# no tags assigned to this eventtype
[ssh_open]
search = eventtype=nix_ta_data punct="*__::_*_[]:_(:):_____*__(=)" sshd (session opened) OR (connection from)
search = eventtype=nix_ta_data punct="*__::_*_[]:_(:):_____*__(=)" sshd (session opened) OR (connection from) AND NOT sourcetype=linux_secure
#tags = communicate connect
# example = Dec 17 15:15:12 domU-12-31-39-03-01-11 sshd[24912]: Connection closed by 195.43.9.246
@ -573,7 +586,7 @@ search = eventtype=nix_ta_data userhelper* NOT punct="__*::_*:_*"
###### ADDED FROM UNIX APP ######
[failed_login]
search = eventtype=nix_ta_data "failed login" OR "FAILED LOGIN" OR "Authentication failure" OR "Failed to authenticate user" OR "authentication ERROR" OR "Failed password for"
search = eventtype=nix_ta_data ("failed login" OR "FAILED LOGIN" OR "Authentication failure" OR "Failed to authenticate user" OR "authentication ERROR" OR "Failed password for") AND NOT sourcetype=linux_secure
#tags = authentication
[Failed_SU]

View file

@ -4,6 +4,12 @@
##
##
[script://./bin/docker_metric.sh]
sourcetype = docker_metric
source = docker
interval = 60
disabled = 1
[script://./bin/vmstat_metric.sh]
sourcetype = vmstat_metric
source = vmstat
@ -44,6 +50,12 @@ disabled = 1
############### Event Inputs ###################
################################################
[script://./bin/docker.sh]
interval = 60
sourcetype = docker
source = docker
disabled = 1
[script://./bin/vmstat.sh]
interval = 60
sourcetype = vmstat

View file

@ -91,6 +91,15 @@ FIELDALIAS-dest_nt_host = dest_host as dest_nt_host
## Scripted Metric Inputs
#########################
[docker_metric]
SHOULD_LINEMERGE=false
LINE_BREAKER = ([\r\n]+)
KV_MODE = json
NO_BINARY_CHECK = true
TRUNCATE=1000000
TRANSFORMS-docker-metric-dimensions=eval_dimensions
METRIC-SCHEMA-TRANSFORMS=metric-schema:extract_metrics_docker
[vmstat_metric]
SHOULD_LINEMERGE=false
LINE_BREAKER=(^$|[\r\n]+[\r\n]+)
@ -103,10 +112,12 @@ TRANSFORMS-vmstat-metric-dimensions=eval_dimensions
METRIC-SCHEMA-TRANSFORMS=metric-schema:extract_metrics_vmstat
[cpu_metric]
SHOULD_LINEMERGE=false
LINE_BREAKER=(^$|[\r\n]+[\r\n]+)
# Timestamp extraction settings
TIME_PREFIX = ^
TIME_FORMAT = %m/%d/%y_%H:%M:%S_%Z
MAX_TIMESTAMP_LOOKAHEAD = 25
TRUNCATE=1000000
DATETIME_CONFIG = CURRENT
KV_MODE = none
INDEXED_EXTRACTIONS = CSV
FIELD_DELIMITER=whitespace
@ -165,10 +176,16 @@ METRIC-SCHEMA-TRANSFORMS=metric-schema:extract_metrics_ps
## Scripted Event Inputs
#########################
[cpu]
SHOULD_LINEMERGE=false
LINE_BREAKER=(^$|[\r\n]+[\r\n]+)
LINE_BREAKER=([\r\n]+)Datetime\s+
EVENT_BREAKER=([\r\n]+)Datetime\s+
# Timestamp extraction settings
TIME_PREFIX = \n
TIME_FORMAT = %m/%d/%y_%H:%M:%S_%Z
EVENT_BREAKER_ENABLE=true
SHOULD_LINEMERGE = false
TRUNCATE=1000000
DATETIME_CONFIG = CURRENT
KV_MODE = multi
FIELDALIAS-dest_for_cpu = host as dest
FIELDALIAS-src_for_cpu = host as src
@ -506,6 +523,14 @@ TRUNCATE=1000000
DATETIME_CONFIG = CURRENT
KV_MODE=multi
[docker]
SHOULD_LINEMERGE=false
LINE_BREAKER=(^$|[\r\n]+)
TRUNCATE=1000000
KV_MODE = json
FIELDALIAS-dest_for_docker = host as dest
FIELDALIAS-src_for_docker = host as src
[vmstat]
LINE_BREAKER=(^$|[\r\n]+[\r\n]+)
TRUNCATE=1000000
@ -549,23 +574,10 @@ FIELDALIAS-dest = host as dest
# Stanzas in this section are legacy configuration stanzas
# intended to support parsing of data created by scripts in
# TA-deploymentapps, which has since been retired. Systems that use
# Splunk_TA_nix on the search head but which may be searching data
# TA-unix on the search head but which may be searching data
# from forwarders on which the older scripts are still in use should
# be able to search new and old data seamlessly.
###### Global ######
# [source::...(linux.*|sample.*.linux)]
# TRANSFORMS-force_host_for_linux_eventgen = force_host_for_linux_eventgen
# [source::...(osx.*|sample.*.osx)]
# TRANSFORMS-force_host_for_osx_eventgen = force_host_for_osx_eventgen
# [source::...(solaris.*|sample.*.solaris)]
# TRANSFORMS-force_host_for_solaris_eventgen = force_host_for_solaris_eventgen
# [source::...sample.*.unix]
# TRANSFORMS-force_host_for_unix_eventgen = force_host_for_unix_eventgen
## support for linux only
[Linux:SELinuxConfig]
EVAL-note = "SELinux is a Linux feature that provides a variety of security policies, including U.S. Department of Defense style mandatory access controls, through the use of Linux Security Modules"
@ -638,9 +650,10 @@ FIELDALIAS-dest = host as dest
[source::...Unix:Version]
SHOULD_LINEMERGE = false
FIELDALIAS-family_for_nix_version = os_name as family
EVAL-description = "script"
EVAL-family = coalesce(kernel_name, os_name)
LOOKUP-range_for_nix_version = nix_da_version_range_lookup sourcetype OUTPUTNEW range
FIELDALIAS-version_for_nix_version = os_release as version
EVAL-version = if(isnotnull(kernel_version),os_version,os_release)
FIELDALIAS-cpu_architecture = machine_architecture_name as cpu_architecture
EVAL-os = if(isnotnull(os_name) AND isnotnull(os_release),os_name." ".os_release,null())
EVAL-vendor_product = if(isnotnull(os_name),os_name,null())
@ -728,13 +741,16 @@ EVENT_BREAKER_ENABLE = true
## Event extractions by type
EVAL-app = case(app="ssh", "ssh", app="nix", "nix", true(), app)
REPORT-0authentication_for_linux_secure = remote_login_allowed, remote_login_failure, passwd-auth-failure, bad-su, failed-su, ssh-invalid-user, ssh-login-failed, ssh-login-accepted, ssh-session-close, ssh-disconnect, sshd_authentication_kerberos_success, sshd_authentication_refused, sshd_authentication_tried, sshd_login_restricted, pam_unix_authentication_success, pam_unix_authentication_failure, sudo_cannot_identify, ksu_authentication, ksu_authorization, su_simple, su_authentication, su_successful, wksh_authentication, login_authentication, ftpd_authentication
REPORT-0authentication_for_linux_secure = remote_login_allowed, remote_login_failure, passwd-auth-failure, bad-su, failed-su, sshd-session-login-failed, sshd-session-login-accepted, sshd-session-invalid-user, sshd-session-connection-close, sshd-session-key-negotiation-failed, sshd-session-banner-exchange-failed, sshd-session-shadow-info-error, sshd-session-read-error-timeout, sshd-session-disconnect, sshd-session-closed-for-user, ssh-invalid-user, ssh-login-failed, ssh-login-accepted, ssh-session-close, ssh-disconnect, sshd_authentication_kerberos_success, sshd_authentication_refused, sshd_authentication_tried, sshd_login_restricted, sshd-session-pam_unix_authentication_success, linux_secure_pam_unix_authentication_success, pam_unix_authentication_failure, sudo_cannot_identify, ksu_authentication, ksu_authorization, su_simple, su_authentication, su_successful, wksh_authentication, login_authentication, ftpd_authentication
EVAL-action = if(app="su" AND isnull(action),"success",action)
REPORT-account_management_for_linux_secure = useradd, userdel, userdel-grp, groupdel, groupadd, groupadd-suse
REPORT-password_change_for_linux_secure = pam-passwd-ok, passwd-change-fail
REPORT-firewall = ipfw, ipfw-stealth, ipfw-icmp, pf
REPORT-routing = iptables
EVAL-signature = if(isnotnull(inbound_interface),"firewall",null())
EVAL-signature = if(isnotnull(inbound_interface), "firewall", signature)
EVAL-user_role = if(authentication_service=="pam_unix" AND user=="root", "administator", null())
EVAL-src = if(authentication_service=="pam_unix" AND signature=="session opened for user" AND app=="sudo", dest, src)
EVAL-dest_dns = if((process == "sshd-session" OR process == "sshd") AND (action == "blocked" OR action == "started" OR action == "ended"), dest, null())
REPORT-dest_for_linux_secure = loghost_as_dest
LOOKUP-action_for_linux_secure = nix_action_lookup vendor_action OUTPUTNEW action
@ -786,3 +802,6 @@ SHOULD_LINEMERGE = false
TIME_PREFIX = audit\(
MAX_TIMESTAMP_LOOKAHEAD=23
MAX_DAYS_AGO=3650
EXTRACT-proctitle = .*proctitle=(?<proctitle>.*)$
EXTRACT-execve_command = .*type=EXECVE.*a0=(?<execve_command>.*)$
EVAL-execve_command = replace(execve_command, "a\d+=", "")

View file

@ -262,6 +262,18 @@ authentication = enabled
remote = enabled
## sshd
## Network_Sessions
[eventtype=sshd_session_start]
network = enabled
session = enabled
start = enabled
[eventtype=sshd_session_end]
network = enabled
session = enabled
end = enabled
[eventtype=sshd_authentication]
authentication = enabled
remote = enabled
@ -652,7 +664,7 @@ os = enabled
# Stanzas in this section are legacy configuration stanzas
# intended to support parsing of data created by scripts in
# TA-deploymentapps, which has since been retired. Systems that use
# Splunk_TA_nix on the search head but which may be searching data
# TA-unix on the search head but which may be searching data
# from forwarders on which the older scripts are still in use should
# be able to search new and old data seamlessly.
@ -834,8 +846,6 @@ system = enabled
version = enabled
inventory = enabled
oshost = enabled
cpu = enabled
memory = enabled
## VSFTDP Config

View file

@ -183,6 +183,9 @@ REGEX=[[dhcp_prefix_src]]reuse_lease:\s+lease\s+age.*under.*threshold,\s+reply\s
# Support for omitting the IPv6 Address field when the script output doesn't include an IPv6 Address
INGEST_EVAL = metric_name=sourcetype, entity_type="TA_Nix", OS_name=replace(OSName, "_", " "), IPv6_address = if(IPv6_Address=="?", null(), IPv6_Address)
#[extract_docker_metrics]
#INGEST_EVAL= CPUPct=CPUPct,MemUsage=MemUsage,MemTotal=MemTotal,MemPct=MemPct,NetRX=NetRX,RXps=RXps,NetTX=NetTX,TXps=TXps,BlockRead=BlockRead,BRps=BRps,BlockWrite=BlockWrite,BWps=BWps,Pids=Pids
[extract_df_metrics]
INGEST_EVAL = UsePct=coalesce('UsePct','Capacity','Use'), Size_KB=coalesce('Size','1K_blocks','1024_blocks'), Used_KB='Used', Avail_KB=coalesce('Avail','Available'), INodes=coalesce('INodes','Inodes'), IUsed=coalesce('IUsed','iused','Iused'), IFree=coalesce('IFree','ifree','Ifree'), IUsePct=coalesce('IUsePct','IUse'), Size=coalesce('Size','1K_blocks','1024_blocks'), Avail=coalesce('Avail','Available'), Type=coalesce('Type',"?")
@ -198,7 +201,7 @@ INGEST_EVAL = rReq_PS=r_s, rKB_PS=coalesce(rkB_s, Kb_read, kr_s), rrqmPct=rrqm,
INGEST_EVAL = pctCPU=coalesce(CPU,pctCPU), pctMEM=coalesce(MEM,pctMEM), RSZ_KB=coalesce(RSS,RSZ_KB), VSZ_KB=coalesce(VSZ, VSZ_KB)
[extract_cpu_metric_field]
INGEST_EVAL = pctIdle=coalesce(id,pctIdle), pctIowait=coalesce(wa,pctIowait), pctSystem=coalesce(sy,pctSystem), pctUser=coalesce(us,pctUser), pctNice=coalesce(pctNice,"0"), CPU=coalesce(cpu,CPU)
INGEST_EVAL = pctIdle=coalesce(id,pctIdle), pctIowait=coalesce(wa,pctIowait), pctSystem=coalesce(sy,pctSystem), pctUser=coalesce(us,pctUser), pctNice=coalesce(pctNice,"0")
[metric-schema:extract_metrics_iostat]
METRIC-SCHEMA-MEASURES= _NUMS_EXCEPT_ OS_name, OS_version, IP_address
@ -208,6 +211,10 @@ METRIC-SCHEMA-BLACKLIST-DIMS= OSName
METRIC-SCHEMA-MEASURES= memTotalMB,memFreeMB,memUsedMB,memFreePct,memUsedPct,pgPageOut,swapUsedPct,pgSwapOut,cSwitches,interrupts,forks,processes,threads,loadAvg1mi,waitThreads,interrupts_PS,pgPageIn_PS,pgPageOut_PS
METRIC-SCHEMA-BLACKLIST-DIMS= OSName
[metric-schema:extract_metrics_docker]
METRIC-SCHEMA-MEASURES= _NUMS_EXCEPT_ OS_version
METRIC-SCHEMA-BLACKLIST-DIMS= OSName
[metric-schema:extract_metrics_df]
METRIC-SCHEMA-MEASURES= _NUMS_EXCEPT_ OS_name, OS_version, IP_address, Filesystem, Type, MountedOn, IPv6_Address, IPv6_address
METRIC-SCHEMA-BLACKLIST-DIMS= IPv6_Address
@ -287,25 +294,85 @@ FORMAT = action::"modified" change_type::"AAA" command::$1 user::$2 object_attrs
REGEX = exe=.*\/(\S+)\"
FORMAT = command::$1
## Network_Sessions
# SSHD evnets for OpenSSH >= v9.8
# Jan 3 17:21:38 host sshd-session[1187]: Failed password for devuser from 1X.XX.XX.XX port 1234 ssh2
# Jan 3 11:08:18 host sshd-session[224962]: message repeated 2 times: [ Failed password for devuser from 1X.XX.XX.XX port 1234 ssh2]
[sshd-session-login-failed]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(?i)(failed\s+password).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))
FORMAT = action::"blocked" src_ip::$3 user::$2 signature::$1
# Jan 3 17:21:42 host sshd-session[1187]: Accepted password for devuser from 1X.XX.XX.XX port 1234 ssh2
[sshd-session-login-accepted]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(?i)(Accepted\s+password).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))
FORMAT = action::"started" signature::$1 user::$2 src_ip::$3
# Jan 3 10:07:28 host sshd-session[147610]: Connection closed by invalid user ubuntu 1X.XX.XX.XX port 1234 [preauth]
[sshd-session-invalid-user]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(?i)(Connection\s+closed\s+by\s+invalid user).*?(\S+)\s+.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))
FORMAT = action::"blocked" signature::$1 user::$2 src_ip::$3
# Jan 3 10:07:28 host sshd-session[147610]: Connection closed by 1X.XX.XX.XX port 1234
[sshd-session-connection-close]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(?i)(Connection\s+closed)\s+by\s+((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))
FORMAT = action::"ended" signature::$1 src_ip::$2
# Jan 3 09:54:47 host sshd-session[146590]: Unable to negotiate with 1X.XX.XX.XX port 1234: no matching host key type found. Their offer: ssh-rsa,ssh-dss [preauth]
[sshd-session-key-negotiation-failed]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+Unable\s+to\s+negotiate\s+with\s+((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))[^:]+:\s+no\s+matching\s+host\s+key\s+type\s+found
FORMAT = action::"blocked" signature::"Unable to negotiate: no matching host key type found" src_ip::$1
# Jan 3 07:08:37 host sshd-session[133482]: banner exchange: Connection from 1X.XX.XX.XX port 1234: invalid format
[sshd-session-banner-exchange-failed]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+banner\s+exchange\s*:\s+.*?\S+\s+from\s+((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))[^:]+:\s*invalid\s+format
FORMAT = action::"blocked" signature::"banner exchange: invalid format" src_ip::$1
# Jan 2 18:13:08 host sshd-session[8962]: error: Could not get shadow information for NOUSER
[sshd-session-shadow-info-error]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+error:\s+(Could\s+not\s+get\s+shadow\s+information)\s+for\s+(\S+)
FORMAT = action::"blocked" signature::$1 user::$2
# Jan 3 05:46:01 host sshd-session[125949]: pam_unix(sshd:session): session opened for user ec2-user(uid=1000) by ec2-user(uid=0)
[sshd-session-pam_unix_authentication_success]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+pam_unix\([^:]+:\w+\)\:\s+(session\s+opened\s+for\s+user)\s+([^\s\(]+)(?:\(uid=(\d+)\))?\s+by\s+([^\s\(]+)(?:\(uid=(\d+)\))?
FORMAT = action::"started" signature::$1 user::$2 user_id::$3 src_user::$4 src_user_id::$5
# Jan 3 05:46:01 host sshd-session[125949]: Read error from remote host 1X.XX.XX.XX port 1234: Connection timed out
[sshd-session-read-error-timeout]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+Read\s+error\s+from\s+remote\s+host\s+((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))[^:]+:\s+(Connection\s+timed\s+out)
FORMAT = action::"ended" src_ip::$1 signature::$2
# Jan 3 11:15:07 host sshd-session[226274]: Disconnected from user devuser 1X.XX.XX.XX port 1234
[sshd-session-disconnect]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+(?i)(Disconnected\s+from\s+user).*?(\S+)\s+((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))
FORMAT = action::"ended" signature::$1 user::$2 src_ip::$3
# Jan 3 10:07:28 host sshd-session[147610]: pam_unix(sshd:session): session closed for user ec2-user
[sshd-session-closed-for-user]
REGEX = (?:sshd-session|sshd)\[\d+\]\:\s+pam_unix\([^:]+:\w+\)\:\s+(session\s+closed\s+for\s+user)\s+([^\s\(]+)$
FORMAT = action::"ended" signature::$1 user::$2
## Authentication
# Jan 14 12:14:04 host sshd[16247]: Accepted publickey for mark from ::ffff:XXX.XXX.XX.XXX port 50710 ssh2
# Aug 21 11:25:06 host sshd[2544]: Accepted keyboard-interactive/pam for root from XXX.XXX.XX.XXX port 1274 ssh2
[ssh-login-accepted]
REGEX = (?:sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(Accepted).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+)\s+\w?\s*(ssh\d))?
REGEX = (?:sshd|sshd-session)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(Accepted).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+))?(?:\s+\w*\s*(ssh\d))?
FORMAT = app::"ssh" action::"success" vendor_action::$1 user::$2 src::$3 src_port::$4 sshd_protocol::$5
# Aug 21 10:31:01 host sshd[1468]: error: PAM: Authentication failure for root from XXX.XXX.XX.XXX
# Nov 5 11:37:47 host sshd[3003]: Failed password for root from XXX.XXX.XX.XXX port 58356 ssh2
# Jan 3 17:21:38 host sshd-session[1187]: Failed password for devuser from 1X.XX.XX.XX port 1234 ssh2
# Jan 3 11:08:18 host sshd-session[224962]: message repeated 2 times: [ Failed password for devuser from 1X.XX.XX.XX port 1234 ssh2]
[ssh-login-failed]
REGEX = (?:sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(failure|Failed).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+)\s+\w?\s*(ssh\d))?
REGEX = (?:sshd|sshd-session)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(failure|Failed).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+))?(?:\s+\w*\s*(ssh\d))?
FORMAT = app::"ssh" action::"failure" vendor_action::$1 src::$3 user::$2 reason::"Failed password" src_port::$4 sshd_protocol::$5
# Apr 14 12:14:04 host sshd[16247]: Failed password for invalid user player from XXX.XXX.XX.XXX port 343 ssh2
# Apr 24 04:02:57 magmum.google.com sshd[12128]: Invalid user player from XXX.XXX.XX.XXX
[ssh-invalid-user]
REGEX = (?:sshd)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(Invalid user|invalid user).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+)\s+\w?\s*(ssh\d))?
REGEX = (?:sshd|sshd-session)\[\d+\]\:\s+(?:\[[^]]+]\s+)?.*?(Invalid user|invalid user).*?(\S+)\s+from.*?((?::?[0-9a-fA-F:]{0,4}:[0-9a-fA-F:]*[.\d]*)|(?:[\d+\.]+))(?:\s+port\s+(\S+))?(?:\s+\w*\s*(ssh\d))?
FORMAT = app::"ssh" action::"failure" src::$3 user::$2 reason::$1 src_port::$4 sshd_protocol::$5
@ -323,8 +390,9 @@ REGEX = .* ((?:session|Connection) (?:opened|closed))(?: for user ([^\s\(]+))?(?
FORMAT = name::$1 user::$2 user_id::$3 src_ip::$4
# Apr 24 04:02:57 magmum.google.com sshd[12128]: Received disconnect from XXX.XXX.XX.XXX: 11: Bye Bye
# Apr 24 04:02:57 magmum.google.com sshd[12128]: Received disconnect from XXX:XXX:XX:XXX:XXX:XXX port 123123:11: disconnected by user
[ssh-disconnect]
REGEX = (Received disconnect) from ([^\s]+):
REGEX = (Received disconnect) from ([^\s]+:[a-fA-F0-9.]+|::|[\d.]+)
FORMAT = name::$1 src_ip::$2
[sshd_authentication_kerberos_success]
@ -351,6 +419,10 @@ FORMAT = app::"ssh" action::$1 src::$3 user::$4 reason::"other" src_user::$2
REGEX = pam_unix\(([^:]+):\w+\)\:\s+(session\s+opened)\s+for\s+user\s+([^\s\(]+)(?:\(uid=(\d+)\))?\s+by\s+([^\s\(]+)(?:\(uid=(\d+)\))?
FORMAT = app::"$1" vendor_action::"$2" user::$3 user_id::$4 src_user::$5 action::"success" src_user_id::$6
[linux_secure_pam_unix_authentication_success]
REGEX = pam_unix\(([^:]+):\w+\)\:\s+(session\s+opened\s+for\s+user)\s+([^\s\(]+)(?:\(uid=(\d+)\))?\s+by\s+([^\s\(]+)(?:\(uid=(\d+)\))?
FORMAT = app::"$1" signature::$2 authentication_service::"pam_unix" user::$3 user_id::$4 src_user::$5 action::"success" src_user_id::$6 src_user_type::"user" user_type::"user"
[passwd-auth-failure]
REGEX = (passwd)\[(?:\d+)\]:\s+User\s+(\w+):\s+(?:Authentication failure)
FORMAT = app::$1 action::"failure" user::$2 reason::"Authentication failure"
@ -459,7 +531,7 @@ FORMAT = signature::$1
# Stanzas in this section are legacy configuration stanzas
# intended to support parsing of data created by scripts in
# TA-deploymentapps, which has since been retired. Systems that use
# Splunk_TA_nix on the search head but which may be searching data
# TA-unix on the search head but which may be searching data
# from forwarders on which the older scripts are still in use should
# be able to search new and old data seamlessly.
@ -469,26 +541,6 @@ FORMAT = signature::$1
##
[force_host_for_linux_eventgen]
DEST_KEY = MetaData:Host
REGEX = .
FORMAT = host::ACME-001
[force_host_for_osx_eventgen]
DEST_KEY = MetaData:Host
REGEX = .
FORMAT = host::ACME-002
[force_host_for_solaris_eventgen]
DEST_KEY = MetaData:Host
REGEX = .
FORMAT = host::ACME-003
[force_host_for_unix_eventgen]
DEST_KEY = MetaData:Host
REGEX = .
FORMAT = host::ACME-004
## Service
[nix_linux_service_startmode_lookup]
filename = nix_linux_service_startmodes.csv
@ -497,10 +549,6 @@ filename = nix_linux_service_startmodes.csv
[nix_da_update_status_lookup]
filename = nix_da_update_status.csv
[Description_for_installedupdates]
REGEX = ^Description=([^\r\n]+)
FORMAT = Description::$1
## Version
[nix_da_version_range_lookup]
filename = nix_da_version_ranges.csv
@ -508,24 +556,4 @@ filename = nix_da_version_ranges.csv
[nix_linux_audit_action_lookup]
filename = nix_linux_audit_action_object_category.csv
[force_host_for_linux_cpu]
DEST_KEY=MetaData:Host
REGEX=^\S+\s+\S+\s+\S+\s+(\S+)
FORMAT=host::$1
[force_host_for_linux_memory]
DEST_KEY=MetaData:Host
REGEX=^\S+\s+\S+\s+\S+\s+(\S+)
FORMAT=host::$1
[force_host_for_linux_io]
DEST_KEY=MetaData:Host
REGEX=^\S+\s+\S+\s+\S+\s+(\S+)
FORMAT=host::$1
[force_host_for_linux_disk]
DEST_KEY=MetaData:Host
REGEX=^\S+\s+\S+\s+\S+\s+(\S+)
FORMAT=host::$1
###### END CONTENT IMPORTED FROM TA-deploymentapps ######

153
docs/ReleaseNotes.md Normal file
View file

@ -0,0 +1,153 @@
# Technical Add-on for Unix and Linux
## Version 10.0.0.1 (2025-02-19)
Fix report CPU_TYPE in hardware.sh for RPIs
Changes:
* For CPU_TYPE in hardware.sh, report something if /proc/cpuinfo does not
contain processor model information
## Version 10.0.0.0 (2025-02-05)
Merge in Splunk Add-On for Unix and Linux version 10.0.0
## Version 9.2.0.13 (2025-02-03)
Fix alignment and fix packages for Arch Linux
Changes:
* Align columns with "column -t"
* Add Arch Linux support in packages.sh
## Version 9.2.0.12 (2025-01-25)
Add Version to update.sh for Darwin
Changes:
* Add version to update.sh for Darwin
## Version 9.2.0.11 (2025-01-25)
Fix Darwin Scripts and Document Sudo
Changes:
* Use sudo in service.sh for Darwin to find user services if not running as root
* Fix parsing the output of softwareupdate command on Darwin in update.sh
* Better document usage of sudo in docs/Sudo.md
## Version 9.2.0.10 (2025-01-25)
Fix OpenBSD Support and Other Bugs
Changes:
* Fix OpenBSD cpu.sh output to match others
* Fix OpenBSD df.sh output (no need for %% here)
* Do not use sudo or doas when running as root
* Use #!/usr/bin/env bash to support OpenBSD in run_nix_ta_commands
* Fix rsyslog example to trim whitespace in run_nix_ta_commands
* Add /usr/local/sbin:/usr/local/bin to PATH in run_nix_ta_commands
* Fix getting hour and minute for OpenBSD in run_nix_ta_commands
"08" shows up to printf as octal
* Support difference in OpenBSD logger command:
Requires modifying /etc/syslog.conf and setting facility in /etc/nix_ta.conf
## Version 9.2.0.9 (2025-01-25)
Support OpenBSD
Changes:
* Add OpenBSD support to the scripts
* Fix sysctl usage for FreeBSD in a couple places
## Version 9.2.0.8 (2025-01-23)
Fix df.sh and df_metric.sh
Changes:
* Fix Linux when df outputs a "-"
* Exclude efivars partitions for Linux
* Fix the output on Darwin to match Linux output
## Version 9.2.0.7 (2025-01-20)
Fix run_nix_ta_commands script
Changes:
* Make run_nix_ta_commands (in extra) use /etc/nix_ta.conf for its settings
instead of hard-coding them in the script
## Version 9.2.0.6 (2025-01-17)
Fix docker script and props
Changes:
* Fix output for docker script (handle lines that didn't have values)
* Fix props.conf LINE_BREAKER for docker
## Version 9.2.0.5 (2025-01-11)
Add script for docker events/metrics and support running TA outside of Splunk
Changes:
* Add docker.sh and docker_metric.sh for collecting docker events/metrics
* Add helper script to extra/ to run the TA commands on systems without
a Splunk forwarder. The commands can be sent to a syslog server.
This script is useful for systems with small or read-only filesystems that
cannot support a Universal Forwarder.
* Add syslog_inputs_nix_ta app to extra/ for ingesting the data from syslog
## Version 9.2.0.4 (2025-01-11)
Make distro_name work everywhere
Changes:
* For MacOS, print MacOS for distro_name
* For others, print $KERNEL for distro_name
## Version 9.2.0.3 (2025-01-11)
Fix bug in 9.2.0.2
Changes:
* Add code I forgot for machine_arch for Linux
* Add Makefile to make making releases easier
## Version 9.2.0.2 (2025-01-11)
Improvements for version.sh
Changes:
* Include kernel_release, kernel_version, and distro_name
* For Linux and MacOS, use actual OS versions/releases instead of
kernel version/release
## Version 9.2.0.1 (2025-01-09)
Initial fork of the Splunk Add-on for Unix and Linux
Changes:
* Use ip command to determine IP address
('hostname -I' does not work on all Linux systems)
* Filter out multiple listing of the same btrfs volume
* Use mktemp for temp files (for times when the TA may be run outside of Splunk)
* If running rlog.sh outside of Splunk, use $HOME to store seek file
* Debian also uses apt
* Arch Linux uses pacman
* Add use of sudo -n for 'apt update' and 'pacman -Syy'
* vmstat uses "K paged out"
* Replace the use of 'sar' with netstat and vm_stat for MacOS

45
docs/Sudo.md Normal file
View file

@ -0,0 +1,45 @@
# Sudo Usage
Some commands may need to use sudo or doas to execute. Below is documentation
for those cases.
## MacOS/Darwin service.sh
The service.sh script searches users' home directories and a splunk user does
not have rights to do that.
Create a file like /etc/sudoers.d/splunk and add:
```
splunk ALL=(root) NOPASSWD: /usr/bin/find /Users -name loginwindow.plist
```
## Docker
Either add the splunk user to the docker group or run the command with sudo.
To make sudo work, create a file like /etc/sudoers.d/splunk and add:
```
splunk ALL=(root) NOPASSWD: /usr/bin/docker stats --no-stream --no-trunc --all
splunk ALL=(root) NOPASSWD: /usr/bin/docker ps --all --no-trunc --format *
splunk ALL=(root) NOPASSWD: /usr/bin/docker inspect -f *
```
## Debian/Ubuntu apt update
A splunk user does not have the ability to update the package cache.
To make sudo work, create a file like /etc/sudoers.d/splunk and add:
```
splunk ALL=(root) NOPASSWD: /usr/bin/apt update
```
## Arch Linux pacman update cache
A splunk user does not have the ability to update the package cache.
To make sudo work, create a file like /etc/sudoers.d/splunk and add:
```
splunk ALL=(root) NOPASSWD: /usr/bin/pacman -Syy
```

180
extra/run_nix_ta_commands Executable file
View file

@ -0,0 +1,180 @@
#!/usr/bin/env bash
# This script allows getting the Techical Add-on for Unix and Linux data into
# Splunk from systems that are not running a Splunk Universal Forwarder.
# This is useful for systems with small or read-only file-systems.
#
# ## Sample rsyslog.conf:
# # Config for handling remote logs
# template(name="RemoteLogs" type="string" string="/share/syslog/%FROMHOST%/%$.myprogramname%/%$.myprogramname%-%$YEAR%-%$MONTH%-%$DAY%.log")
# # Write raw messages for splunk logs
# template(name="RawMessageOnly" type="string" string="%$.mymsg%\n")
# # Look for logs with nix_ta to apply RawMessagesOnly and send to RemoteLogs
# if ($syslogtag startswith 'nix_ta_') then {
# set $.mymsg = ltrim(rtrim(replace($msg, "#011", " ")));
# action(type="omfile" dynaFile="RemoteLogs" template="RawMessageOnly"
# fileCreateMode="0644" dirCreateMode="0755"
# fileOwner="root" fileGroup="splunk"
# dirOwner="root" dirGroup="splunk")
# stop
# }
# # End of sample rsyslog.conf
#
# ## run_nix_ta_commands configuration file
# * Create a new file (/etc/nix_ta.conf) with the following settings in it
# * ta_home: The directory you copied the Technical Add-on for Unix and Linux files
# * tag_prefix: The events will be sent to syslog with ${tag_prefix}SCRIPTNAME as a tag
# * syslog_server: The UDP syslog server to send events to
# * run_minute: For scripts that have intervals over an hour, which minute to run them
# * run_hour: For scripts that run once a day, which hour to run them
# * facility: For logger commands like OpenBSD that do not support pointing to a syslog_server directly
# Set to something like "local3.info"
#
# ## Using syslog facility instead of specifying a syslog server with logger
# Using $facility when logger does not support specifying $syslog_server:
# Modify local syslog server to send logs for $facility to the $syslog_server
# On OpenBSD, an example for /etc/syslog.conf is:
# local3.* @192.168.1.1
#
# ## Cron job example:
# * * * * * /path/to/script/run_nix_ta_commands
# Ensure the logger command is available
which logger > /dev/null 2>&1 || { echo "Error: The logger command is required for this script"; exit; }
# Ensure PATH has correct paths
export PATH=$PATH:/usr/local/sbin:/usr/local/bin
# Example/default settings -- override in /etc/nix_ta.conf
ta_home=/srv/TA-unix
tag_prefix=nix_ta_
syslog_server=192.168.1.1
run_minute=2
run_hour=6
facility=
[ -r /etc/nix_ta.conf ] && . /etc/nix_ta.conf
# Get the current minute now to be consistent through the script run
minute=$(printf "%d" $((10#$(date +%M))))
# Get the current hour now to be consistent through the script run
hour=$(printf "%d" $((10#$(date +%H))))
# Set defaults disabling force-mode and list-mode
force=0
list=0
usage() {
echo "usage: $(basename $0) [-h] [-f] [-l] [script]"
echo " -h: print this help text"
echo " -f: run all enabled scripts regardless of interval"
echo " -l: list scripts, enabled status, and interval (if enabled)"
exit
}
# Get the command line options
while getopts ":hlf" opt; do
case $opt in
f) force=1 ;;
l) list=1 ;;
*) usage ;;
esac
done
shift $((OPTIND -1))
# Function to actually run the script and pipe it to logger
runit() {
[ -z "$1" ] && return 1
if [ -x $ta_home/bin/$1.sh ]; then
if [ -n "$facility" ]; then
{ $ta_home/bin/$1.sh 2> /dev/null; echo; } | logger -p $facility -t ${tag_prefix}$(echo $1|tr '[A-Z]' '[a-z]')
else
{ $ta_home/bin/$1.sh 2> /dev/null; echo; } | logger -n $syslog_server -t ${tag_prefix}$(echo $1|tr '[A-Z]' '[a-z]')
fi
else
echo Could not find $1 in $ta_home/bin
return 1
fi
}
# Check the inputs.conf to see if any of the checks are disabled
declare -A scripts
declare -A intervals
# Load defaults first
if [ -r $ta_home/default/inputs.conf ]; then
eval $(awk -F '[=#]' '
/^\[/{name=""}
/^\[script:\/\//{n=split($1,a,"/");name=gensub(/\.[a-z]+\]/,"",1,a[n]);printf "scripts[%s]=1\nintervals[%s]=60\n",name,name}
name!="" && $1~/(^|\s*)disabled(\s*|$)/ {disabled=gensub(/(^ | $)/,"","g",gensub(/true/,"1",1,gensub(/false/,"0",1,$2)));printf "scripts[%s]=%s\n",name,disabled}
name!="" && $1~/(^|\s*)interval(\s*|$)/ {interval=gensub(/(^ | $)/,"","g",$2);printf "intervals[%s]=%s\n",name,interval}
' $ta_home/default/inputs.conf)
fi
# See if any defaults are overridden in the local directory
if [ -r $ta_home/local/inputs.conf ]; then
eval $(awk -F '[=#]' '
/^\[/{name="";disabled=1;interval=60}
/^\[script:\/\//{n=split($1,a,"/");name=gensub(/\.[a-z]+\]/,"",1,a[n])}
name!="" && $1~/(^|\s*)disabled(\s*|$)/ {disabled=gensub(/(^ | $)/,"","g",gensub(/true/,"1",1,gensub(/false/,"0",1,$2)));printf "scripts[%s]=%s\n",name,disabled}
name!="" && $1~/(^|\s*)interval(\s*|$)/ {interval=gensub(/(^ | $)/,"","g",$2);printf "intervals[%s]=%s\n",name,interval}
' $ta_home/local/inputs.conf)
fi
# If -l, just print the scripts
if [ $list = 1 ]; then
for script in "${!scripts[@]}"; do
if [ "${scripts[$script]}" = "0" ]; then
echo "$script is enabled (${intervals[$script]} seconds)"
else
echo "$script is disabled"
fi
done
exit
fi
# If a script is specified on the command line, run it (even if disabled)
if [ "$1" ]; then
runit $1
exit
fi
# Without -l or -f, loop through the enabled scripts and run them at their interval
for script in "${!scripts[@]}"; do
# Only run enabled scripts
if [ "${scripts[$script]}" = "0" ]; then
i=${intervals[$script]}
[ $i -lt 60 ] && i=60
min=$((i/60))
# If -f, always run each script
if [ $force = 1 ]; then
runit $script
# If interval is 60 seconds or less, run every minute
elif [ $min -le 1 ]; then
runit $script
# If the current minute is divisible by the number of interval minutes, run
# example: 600 is 5 minutes, it'll run at 0, 5, 10, 15, ... minutes
elif [ $((minute % min)) = 0 ]; then
runit $script
# If interval is an hour or more
elif [ $min -gt 60 ]; then
hr=$((i/60/60))
# If interval is 1 hour or less, run every hour on $run_minute
if [ $hr -le 1 ] && [ $minute = $run_minute ]; then
runit $script
# If the current hour is divisible by the number of interval hours, run
# example: 21600 is 6 hours, it'll run at 0, 6, 12, 18 hours
elif [ $((hour % hr)) = 0 ] && [ $minute = $run_minute ]; then
runit $script
# If the number of hours is 24 or more, run every day at $run_hour:$run_minute
elif [ $hr -ge 24 ] && [ $hour = $run_hour ] && [ $minute = $run_minute ]; then
runit $script
fi
fi
fi
done

View file

@ -0,0 +1,4 @@
# Application-level permissions
[]
access = read : [ * ], write : [ admin , sc_admin ]
export = system

View file

@ -1,359 +0,0 @@
{
"version": "1.0",
"date": "2024-10-18T12:52:23.073000921Z",
"hashAlgorithm": "SHA-256",
"app": {
"id": 833,
"version": "9.2.0",
"files": [
{
"path": "LICENSES/Apache-2.0.txt",
"hash": "d3910dee6fe9fe134856d76268fe82adb1ade1ecf51b3568b7da6b94894b88f3"
},
{
"path": "LICENSES/LicenseRef-Splunk-8-2021.txt",
"hash": "37906d637abbbeca35cfb2efcb658cabbc0208d101848372c1e55fbf9ba62e47"
},
{
"path": "README/restmap.conf.spec",
"hash": "5cc8f9508cd792137e1a2129763dd78e9275a0c2f8d3cf7fc25b72848a07d869"
},
{
"path": "README.txt",
"hash": "106e6203d3ff66f04cac953385cb517cff459b572f8d52adf71a8a59c5851776"
},
{
"path": "THIRDPARTY",
"hash": "6340a3cf0959b37d83e10ce4e12bc4ab53d2ae2729ee506451b8d554418d1ab3"
},
{
"path": "VERSION",
"hash": "4b083d27782e80fd5bce34252adc7de9e9ab611475e170cb507e49586483025e"
},
{
"path": "app.manifest",
"hash": "24b4bb6f47bc1472038f5c983ec91705052162da89555f52a78c9f3c830cfd82"
},
{
"path": "appserver/static/appIcon.png",
"hash": "6cb62d7fd2d90e69d66c3e4fbede9692f9d650176a7a9ec06edd4026f1de580a"
},
{
"path": "appserver/static/components/js_sdk_extensions/common.js",
"hash": "295fe307ec286b9b4eb89c4b59dbd6204376e63b7346c26fd1b087446db372c2"
},
{
"path": "appserver/static/components/js_sdk_extensions/monitor_inputs.js",
"hash": "27af704acaeb3b98c78ad5322a6171e1b748b5650be809f5d92a4e5618529123"
},
{
"path": "appserver/static/components/js_sdk_extensions/scripted_inputs.js",
"hash": "6fe5d6f31a60a86d9988170e1641f13eb315351f890c2247c6de83b3aa372e26"
},
{
"path": "appserver/static/setup.css",
"hash": "f27882e6a07bbd87f99f95d77211439e71959efae6d52ce4771ce26d06e0bcc9"
},
{
"path": "appserver/static/setup.js",
"hash": "a3d4e2567779b605a97daa3ced2fc49a8e487a5ec4ee95080392824eb74e7e11"
},
{
"path": "appserver/static/setup_cloud.js",
"hash": "00875c907fd0dc80fa5d05130c28410a8abd99a0ff43da86c6af87e01d8a21da"
},
{
"path": "bin/bandwidth.sh",
"hash": "14682eacdc5ab8849ce3e786c05d0140ea166b6f28403106e433048c09533146"
},
{
"path": "bin/common.sh",
"hash": "6569707362169122ec6a41c9345ed00e09e0913e3855ccb68a21ade3c1c9012d"
},
{
"path": "bin/cpu.sh",
"hash": "e34d912324ceb3f6add524722adc9057b4177015fad844a5e37634ef40cbb9c7"
},
{
"path": "bin/cpu_metric.sh",
"hash": "2d175a98ded5f141b20fd3b3847217447b5489b4d989512d8b8679a4f2777a0b"
},
{
"path": "bin/df.sh",
"hash": "27b0ad779340e6bd8a26e296ce9b0b9cd2721eaadcf4669e5579560a676c9db7"
},
{
"path": "bin/df_metric.sh",
"hash": "4457b92d8d8ee24441eb38df2134113f5a821111b7c3573b48313adcee39d3e8"
},
{
"path": "bin/hardware.sh",
"hash": "20e341826d21047e9cc3b7cd632422f6b9a0364282333616c1f912b4dddb7093"
},
{
"path": "bin/interfaces.sh",
"hash": "ebdd6823f6db05bc76ebdbfb61d1fda63959fd334cf59d2e038ea7bae64355b7"
},
{
"path": "bin/interfaces_metric.sh",
"hash": "9458deb6ba4c56a22264df75d42945e170f6f1a729d93220617c85810733ef19"
},
{
"path": "bin/iostat.sh",
"hash": "505a4694c4879fd8ed155394be51431c9839fc9f980077abb0416f844f09d722"
},
{
"path": "bin/iostat_metric.sh",
"hash": "4af68e89e6a93fa34ccd724ff78a509b7868bc06e60a4f16a6aa24d300d8efc8"
},
{
"path": "bin/lastlog.sh",
"hash": "8d8c0744767d9426cb98122d33eb6acd5447db4a03cfccfd5fdc014f1e15ea3e"
},
{
"path": "bin/lsof.sh",
"hash": "a98a9c64496a081c395e00b692f5eca25ae186cc050c0f31d5425a561fdc63a1"
},
{
"path": "bin/netstat.sh",
"hash": "a5ef9833cf21c6572431f32991d153a625510a4b0553fe6f56d07bb4f4914b2e"
},
{
"path": "bin/nfsiostat.sh",
"hash": "eccc2bf3701840173206ecf7603c20861b4ce106b6be795df2fa312744958107"
},
{
"path": "bin/openPorts.sh",
"hash": "9f7cb2a7f9e8b43ceb7e22930ea125855e64527caa13d76b5c219ec473b899c5"
},
{
"path": "bin/openPortsEnhanced.sh",
"hash": "d7e19798aec7fb3244b6fe36fce28ca3fc8951a0e38d0516f5ef8c1b06197246"
},
{
"path": "bin/package.sh",
"hash": "d9da2664cc2b913285d595e7c74dab9e5a6f1703d44e8f517e9b62a5ba70496a"
},
{
"path": "bin/passwd.sh",
"hash": "4ab37e3c9d07842777ed42f8b22adfe8fe05a9ab0758e833fdc885a26237bafe"
},
{
"path": "bin/protocol.sh",
"hash": "61e372f670cb74131890a2c0ff381891c83337687b6809f31bf920a99f5bd432"
},
{
"path": "bin/ps.sh",
"hash": "3a6ebc99c1b5207d54c885338cf06b22f343c1f64a6048d03fd0bf48b82d41b5"
},
{
"path": "bin/ps_metric.sh",
"hash": "0c3dc356f47728b9b99be79fffe40256eded1644f599b1bbe8b1a9e8db05b10d"
},
{
"path": "bin/rlog.sh",
"hash": "271fcaf091527670df3e794c29d7bf57d1371909c72c25d56c79dd136b029513"
},
{
"path": "bin/selinuxChecker.sh",
"hash": "07135df789924f8d4f5ae8228ccbfe0a5e47756de202fcf00a019a12712d8312"
},
{
"path": "bin/service.sh",
"hash": "d579051391bd1af365bdda6016e3529009e0e7b62e1846fdcdb755b36f0d7c49"
},
{
"path": "bin/setup.sh",
"hash": "b0263d112fa183411bfe141840d697217025856d44fa67be6d14b240728b7062"
},
{
"path": "bin/setupservice.py",
"hash": "c69d1b0b4a10ec966c2e752b7ec1c3f4be5ca3721626bbab62ddfe1509d15137"
},
{
"path": "bin/sshdChecker.sh",
"hash": "ba9ada21b413a1f7ea5ab7850314e96b03c8a3369267af24d9cf2d8f76edb6dc"
},
{
"path": "bin/time.sh",
"hash": "5ad0ed71a9c4637046da43656aea4a614e331217fb707e9df7443aaa6036eeba"
},
{
"path": "bin/top.sh",
"hash": "f380506de00a3bb51d9351108057e498cd8211e3ade7c16fa65121d3ff66ba1d"
},
{
"path": "bin/update.sh",
"hash": "048f6e678f873d2b856ec851c52389d9f8d5ccde0fee0ead0dcf5348cc3cb587"
},
{
"path": "bin/uptime.sh",
"hash": "2770952e0c29a92e37d2d23a8a93223812e2facd4597c50e3e832439fdbdf600"
},
{
"path": "bin/usersWithLoginPrivs.sh",
"hash": "0006baa9bc57e6b5711e557b6532b8c48b29d42bca6364d664042d2aa6f2cf12"
},
{
"path": "bin/version.sh",
"hash": "4d484fc3e1853d0e07d47ba9c4401266a1fbe0712a554e9eeaeb835b96d8a59f"
},
{
"path": "bin/vmstat.sh",
"hash": "b816aa5e67ad18b995eb577e16ca7c91ae3ecdeeb019d0b79321ade83a90daef"
},
{
"path": "bin/vmstat_metric.sh",
"hash": "47df351e2afd7abedb49f8d38f5350ce6276fdb512005ba56e7ff9692f581515"
},
{
"path": "bin/vsftpdChecker.sh",
"hash": "0009c03f72289e5b7b692cb74951382d1a6d4c3698ef5b08b74e468f3dfe199f"
},
{
"path": "bin/who.sh",
"hash": "47318dee6246abfd577984383ac134225a84e0dcf0753413f88b7f2be5a8087d"
},
{
"path": "default/app.conf",
"hash": "451c717df6073aabd78b5ba4abb33ac71b6d61df8d46a243913b01ed9ac77040"
},
{
"path": "default/data/ui/nav/default.xml",
"hash": "36078398f91fa377c21f2369271797cc0016b8ba1a6f271e327cce2809f2711d"
},
{
"path": "default/data/ui/views/ta_nix_configuration.env_cloud.xml",
"hash": "7176b693e2eeb2757d6a5a9651e793141a52b5b36f4b229c31f4ab3e970e8510"
},
{
"path": "default/data/ui/views/ta_nix_configuration.xml",
"hash": "2d30308510e08aea0a190984fda45b708ab373768796494202a4813c37ef74d2"
},
{
"path": "default/eventtypes.conf",
"hash": "c52b63bf8b429e406a1488c59c1945531123bed647b08460d85ca3a6a4f8f81e"
},
{
"path": "default/inputs.conf",
"hash": "0eff320f7aba6d35e27e8a0ae0837ad6c4340f9e84a9cdfb71e8162a97ecc782"
},
{
"path": "default/macros.conf",
"hash": "0daf589bcfbd430f45b55ed3f3d0784f8ad6e79d75300fac9c2604a79fc7f4dc"
},
{
"path": "default/props.conf",
"hash": "8742759e63baf3dc737adecec95fb7370741cb5f2268064593cb2e5a1ba8b260"
},
{
"path": "default/restmap.conf",
"hash": "2774f5332efc8bfeebb88a1d771b8d65cca9197666d0c5e9a4a371b8ed468d73"
},
{
"path": "default/tags.conf",
"hash": "ad29e489018a892f8d50731e32efa48a01dcdb438096d443f7b6e068cfd1ca15"
},
{
"path": "default/transforms.conf",
"hash": "d13792dde1aa85d9e864782787948d6f10b888e4a689d6668de3cc604e2ad1ab"
},
{
"path": "default/web.conf",
"hash": "75f12a6541d22c27d526ab544973398ae4b6d5aa1e57e8e4b22e845e564a2e56"
},
{
"path": "lookups/nix_da_update_status.csv",
"hash": "a9a794b39377946e0dcb5f70c9c8ba6114fec1728512c9f39cfb0f3eca46159c"
},
{
"path": "lookups/nix_da_version_ranges.csv",
"hash": "992529c548d8273e073a988d089fbd5c7fa5c1ef47d51243e9da9dfb77eba6d2"
},
{
"path": "lookups/nix_linux_audit_action_object_category.csv",
"hash": "5838950fd3cade537dea91d1dcdcbd10532457fa7de07d397bfc699e56a19867"
},
{
"path": "lookups/nix_linux_service_startmodes.csv",
"hash": "dd669b358909f4d9be9d0aef9f4720e78a290e422a90ec3e3cdabe39ed9b8be2"
},
{
"path": "lookups/nix_vendor_actions.csv",
"hash": "f287b03905a705fed92dd4a1d1cf060c16b9521aba80b06494af8d5e8530fa97"
},
{
"path": "metadata/default.meta",
"hash": "6fa3057938996152cdfeddb46b20a1c079966ba87a56cf7c13c9d35f3caaf2e7"
},
{
"path": "static/appIcon.png",
"hash": "6cb62d7fd2d90e69d66c3e4fbede9692f9d650176a7a9ec06edd4026f1de580a"
},
{
"path": "static/appIconAlt.png",
"hash": "6cb62d7fd2d90e69d66c3e4fbede9692f9d650176a7a9ec06edd4026f1de580a"
},
{
"path": "static/appIconAlt_2x.png",
"hash": "d7ad6f1263583f5b280b52be4f8806b0d22a4aa6e328a0209212697b6734570c"
},
{
"path": "static/appIconLg.png",
"hash": "d7ad6f1263583f5b280b52be4f8806b0d22a4aa6e328a0209212697b6734570c"
},
{
"path": "static/appIconLg_2x.png",
"hash": "11ca7ef68587f5f1bacbbcb24b85924089724bcf02610b512f899fadac186f34"
},
{
"path": "static/appIcon_2x.png",
"hash": "d7ad6f1263583f5b280b52be4f8806b0d22a4aa6e328a0209212697b6734570c"
}
]
},
"products": [
{
"platform": "splunk",
"product": "enterprise",
"versions": [
"9.0",
"9.1",
"9.2",
"9.3"
],
"architectures": [
"x86_64"
],
"operatingSystems": [
"windows",
"linux",
"macos",
"freebsd",
"solaris",
"aix"
]
},
{
"platform": "splunk",
"product": "cloud",
"versions": [
"9.0",
"9.1",
"9.2",
"9.3"
],
"architectures": [
"x86_64"
],
"operatingSystems": [
"windows",
"linux",
"macos",
"freebsd",
"solaris",
"aix"
]
}
]
}