Skip to content

Instantly share code, notes, and snippets.

@marun
Last active January 28, 2021 06:28
Show Gist options
  • Save marun/0af2c90749bdfc694beb77368d95f2f3 to your computer and use it in GitHub Desktop.
Save marun/0af2c90749bdfc694beb77368d95f2f3 to your computer and use it in GitHub Desktop.
WIP script to ingest must-gather to loki
/usr/bin/env bash |
|
set -o errexit |
set -o nounset |
set -o pipefail |
|
# Ingest logs collected in a must-gather into loki via promtail |
|
if [[ "${LOKI_ADDR}" == "" ]]; then |
>&2 echo "LOKI_ADDR is not set (e.g. LOKI_ADDR=http://localhost:3100)" |
exit 1 |
fi |
|
function ingest-pod-log() { |
local log_file="${1}" |
|
local filename |
filename="$(basename "${log_file}")" |
|
local current_dir |
current_dir="$(dirname "${log_file}")" # 'logs' dir (ignore) |
current_dir="$(dirname "${current_dir}")" # first container dir (ignore) |
current_dir="$(dirname "${current_dir}")" # second container dir |
|
local container |
container="$(basename "${current_dir}")" |
|
current_dir="$(dirname "${current_dir}")" # pod dir |
|
local pod |
pod="$(basename "${current_dir}")" |
|
current_dir="$(dirname "${current_dir}")" # pods dir |
current_dir="$(dirname "${current_dir}")" # namespace dir |
|
local namespace |
namespace="$(basename "${current_dir}")" |
|
local config_file |
config_file="$(mktemp -p "${CONFIG_DIR}")" |
|
# Generate configuration to tmp file. |
# Containing dir will be cleaned up. |
cat <<EOF > "${config_file}" |
# Server isn't required |
server: |
disable: true |
|
client: |
url: ${LOKI_ADDR}/loki/api/v1/push |
|
scrape_configs: |
- job_name: must-gather-pod |
pipeline_stages: |
- regex: |
expression: ^(?s)(?P<time>\\S+?) (?P<content>.*)$ |
- timestamp: |
source: time |
format: RFC3339Nano |
- output: |
source: content |
|
static_configs: |
- labels: |
namespace: ${namespace} |
pod_name: ${pod} |
pod_container_name: ${container} |
filename: ${filename} |
EOF |
echo "Ingesting to loki: ${log_file}" |
cat "${log_file}" | promtail --stdin --config.file="${config_file}" & |
echo "" |
} |
|
function ingest-host-service-log() { |
local log_file="${1}" |
# TODO |
} |
|
function ingest-audit-log() { |
local log_file="${1}" |
|
local filename |
filename="$(basename "${log_file}")" |
|
local node |
node="$(echo "${filename}" | sed -e 's+\(.*\)-audit.*+\1+')" |
|
local apiserver_dir |
apiserver_dir="$(dirname "${log_file}")" |
local apiserver |
apiserver="$(basename "${apiserver_dir}")" |
|
local config_file |
config_file="$(mktemp -p "${CONFIG_DIR}")" |
|
# Generate configuration to tmp file. |
# Containing dir will be cleaned up. |
cat <<EOF > "${config_file}" |
# Server isn't required |
server: |
disable: true |
|
client: |
url: ${LOKI_ADDR}/loki/api/v1/push |
|
scrape_configs: |
- job_name: must-gather-audit |
pipeline_stages: |
- json: |
expressions: |
stage: |
requestURI: |
verb: |
user: |
sourceIPs: |
objectRef: |
responseStatus: |
requestReceivedTimestamp: |
stageTimestamp: |
annotations: |
- json: |
expressions: |
username: |
source: user |
- json: |
expressions: |
resource: |
namespace: |
name: |
source: objectRef |
- json: |
expressions: |
responseCode: code |
source: responseStatus |
- json: |
expressions: |
decision: '"authorization.k8s.io/decision"' |
reason: '"authorization.k8s.io/reason"' |
source: annotations |
- regex: |
expression: ^\[\"(?P<sourceIP>[\d\.]+)\"\] |
source: sourceIPs |
- labels: |
stage: |
requestURI: |
verb: |
username: |
sourceIP: |
resource: |
namespace: |
name: |
responseCode: |
decision: |
- timestamp: |
source: stageTimestamp |
format: RFC3339Nano |
- output: |
source: requestReceivedTimestamp |
|
static_configs: |
- labels: |
node: ${node} |
apiserver: ${apiserver} |
filename: ${filename} |
EOF |
echo "Ingesting to loki: ${log_file}" |
gunzip -c "${log_file}" | promtail --stdin --config.file="${config_file}" |
echo "" |
} |
|
CONFIG_DIR="$(mktemp -d /tmp/loki-ingest-XXX)" |
# deletes the temp directory |
function cleanup { |
rm -rf "$CONFIG_DIR" |
echo "Deleted temp config directory $CONFIG_DIR" |
} |
# register the cleanup function to be called on the EXIT signal |
trap cleanup EXIT |
|
LOG_FILES="$(find -name '*.log')" |
|
for log_file in ${LOG_FILES[@]}; do |
if [[ "${log_file}" == *"/namespaces/"* ]]; then |
ingest-pod-log "${log_file}" |
elif [[ "${log_file}" == *"/host_service_logs/"* ]]; then |
ingest-host-service-log "${log_file}" |
fi |
done |
|
AUDIT_LOG_FILES="$(find -name '*.log.gz')" |
|
for log_file in ${AUDIT_LOG_FILES[@]}; do |
ingest-audit-log "${log_file}" |
done |
|
|
|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment