Skip to content

Instantly share code, notes, and snippets.

@robertomiranda
Created January 18, 2021 10:12
Show Gist options
  • Save robertomiranda/ff57cf2c4b14650c9e1dcbd72f1b6e30 to your computer and use it in GitHub Desktop.
Save robertomiranda/ff57cf2c4b14650c9e1dcbd72f1b6e30 to your computer and use it in GitHub Desktop.
#!/bin/bash -eo pipefail
###############
# Begin Collecting
###############
DATA_URL="https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job?circle-token=$CIRCLE_TOKEN"
WF_DATA=$(curl -s "$DATA_URL")
WF_MESSAGE=$(echo "$WF_DATA" | jq '.message')
# Exit if no Workflow.
if [ "$WF_MESSAGE" = "\"Workflow not found\"" ];
then
echo "No Workflow was found."
echo "Your circle-token parameter may be wrong or you do not have access to this Workflow."
exit 1
fi
WF_ITEMS=$(echo "$WF_DATA" | jq '.items')
WF_LENGTH=$(echo "$WF_ITEMS" | jq length)
# GET URL PATH DATA
VCS_SHORT=$(echo $CIRCLE_BUILD_URL | cut -d"/" -f4)
case $VCS_SHORT in
gh)
VCS=github
;;
bb)
VCS=bitbucket
;;
*)
echo "No VCS found. Error" && exit 1
;;
esac
# Assume the WF is currently running
WF_FINISHED=false
echo -e "Jobs in Workflow: $WF_LENGTH \n"
# Exit if no other jobs in the Workflow.
if [ "$WF_LENGTH" -lt 2 ];
then
echo "Only a single job has been found in the workflow, indicating this reporter is the only job in the pipeline."
echo "Please add other jobs to the Workflow you wish to collect data on to send to Sumologic"
exit 0
fi
#####################
## START MAIN LOOP ##
#####################
# Check the status of all jobs in the workflow that are not this job and wait until they have all finished.
while [ "$WF_FINISHED" = false ]
do
WF_DATA=$(curl -s "$DATA_URL" | jq '.items')
echo "Waiting for other jobs to finish..."
#####
# Send Workflow Data to SumoLogic
#####
mkdir -p /tmp/sumologic-logs/
WF_SL_PAYLOAD=$(curl -s "$DATA_URL" | jq '.')
echo $WF_SL_PAYLOAD > /tmp/sumologic-logs/workflow-collector.json
curl -s -X POST -T /tmp/sumologic-logs/workflow-collector.json $WORKFLOW_HTTP_SOURCE
# for each job in the workflow fetch the status.
# the WF_FINISHED will be assumed true unless one of the jobs in the Workflow is still running
# the flag will then be set back to false.
WF_FINISHED=true
i="0"
################
### JOB LOOP ###
################
while [ $i -lt "$WF_LENGTH" ]
do
echo "looping: $i"
# fetch the job info
JOB_DATA=$(echo "$WF_DATA" | jq --arg i "$i" ".[$i]")
JOB_NUMBER=$(echo "$JOB_DATA" | jq ".job_number")
JOB_STATUS=$(echo "$JOB_DATA" | jq ".status")
JOB_NAME=$(echo "$JOB_DATA" | jq ".name")
# Only check the job if it is not this current job
if [ "$JOB_NUMBER" = "$CIRCLE_BUILD_NUM" ];
then
echo "This is the reporter job. Skipping"
else
# If this job is NOT the current job, check the status
echo "JOB: $JOB_NAME"
echo "JOB NUM: $JOB_NUMBER"
echo "STATUS: $JOB_STATUS"
### This section could be used to send data from the job while it is running. Commenting out this section currently to reduce complexity of dashboard. Updates will be sent when the job completes.
# #####
# # Send Job Data to SumoLogic
# #####
# mkdir -p /tmp/sumologic-logs/
# ###
# # Process Job api 1.1 Data
# ###
# echo
# echo "JOB DATA URL:"
# echo "https://circleci.com/api/v1.1/project/$VCS/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$JOB_NUMBER"
# JOB_DATA_RAW=$(curl -s "https://circleci.com/api/v1.1/project/$VCS/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$JOB_NUMBER?circle-token=$CIRCLE_TOKEN")
# # removing steps,circle_yml, outcome keys from object while the workflow is incomplete.
# JOB_DATA_RAW=$(echo $JOB_DATA_RAW | jq 'del(.circle_yml)' | jq 'del(.steps)')
# # Write the modified data to a file
# echo $JOB_DATA_RAW > /tmp/sumologic-logs/job-collector.json
# curl -s -X POST -T /tmp/sumologic-logs/job-collector.json $JOB_HTTP_SOURCE
###
if [ "$JOB_STATUS" == '"success"' ] || [ "$JOB_STATUS" == '"failed"' ];
then
echo "Job $JOB_NAME $JOB_NUMBER is complete - $JOB_STATUS"
elif [ "$JOB_STATUS" == '"on_hold"' ] || [ "$JOB_STATUS" == '"blocked"' ];
then
# The condition to not block metrics sending when workflow use manually approved steps or is blocked.
echo "Job $JOB_NAME $JOB_NUMBER need manual approval - $JOB_STATUS - skipping"
else
# If it is still running, then mark WF_FINISHED as false.
WF_FINISHED=false
echo "Setting status of WF_FINISHED to false"
fi
fi
echo "rerunning loop"
i="$((i+1))"
echo "increment loop to $i"
echo " ---------- "
echo
done
echo "Waiting 10 seconds"
sleep 10
done
echo
################
# WF COMPLETE #
################
echo
echo "-------------------------------"
echo "All jobs in Workflow complete."
echo "Sending final report."
echo "-------------------------------"
echo
echo
########################################
# Send end-of-workflow data to Sumologic
########################################
WF_SL_PAYLOAD=$(curl -s "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID?circle-token=$CIRCLE_TOKEN" | jq '.')
# Append any custom data to the workflow data
ESCAPED_JSON=$(echo '' | sed -E 's/([^\]|^)"/\1\\"/g')
CUSTOM_DATA=$(eval "echo $ESCAPED_JSON")
if [[ ! -z '' ]] && echo "$CUSTOM_DATA" | jq -e;
then
echo "Appending custom data to the workflow data"
WF_SL_PAYLOAD=$(echo $WF_SL_PAYLOAD | jq -c ". + {\"custom_data\": $CUSTOM_DATA}")
else
echo "No valid custom data found to append to the workflow data"
fi
echo "SENDING FINAL WORKFLOW DATA"
echo $WF_SL_PAYLOAD
echo $WF_SL_PAYLOAD > /tmp/sumologic-logs/workflow-collector.json
curl -s -X POST -T /tmp/sumologic-logs/workflow-collector.json $WORKFLOW_HTTP_SOURCE
########################################
# Send end-of-workflow jobs data to Sumologic
########################################
echo "SENDING FINAL JOB INFORMATION"
i=0
while [ $i -lt "$WF_LENGTH" ]
do
echo "looping: $i"
# fetch the job info
JOB_DATA=$(echo "$WF_DATA" | jq --arg i "$i" ".[$i]")
JOB_NUMBER=$(echo "$JOB_DATA" | jq ".job_number")
JOB_STATUS=$(echo "$JOB_DATA" | jq ".status")
JOB_NAME=$(echo "$JOB_DATA" | jq ".name")
# Only check the job if it is not this current job
if [ "$JOB_NUMBER" = "$CIRCLE_BUILD_NUM" ];
then
echo "This is the reporter job. Skipping"
else
# If this job is NOT the current job, check the status
echo "JOB: $JOB_NAME"
echo "JOB NUM: $JOB_NUMBER"
echo "STATUS: $JOB_STATUS"
#####
# Send Job Data to SumoLogic
#####
mkdir -p /tmp/sumologic-logs/
###
# Process Job api 1.1 Data
###
# If $JOB_NUMBER is null, probably Approval Job. Don't process and send.
if [ "$JOB_NUMBER" = "null" ];
then
echo "Approval Job, skipping"
else
JOB_DATA_RAW=$(curl -s "https://circleci.com/api/v1.1/project/$VCS/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$JOB_NUMBER?circle-token=$CIRCLE_TOKEN")
# removing steps and circle_yml keys from object
JOB_DATA_RAW=$(echo $JOB_DATA_RAW | jq 'del(.circle_yml)' | jq 'del(.steps)')
# manually set job name as it is currently null
JOB_DATA_RAW=$(echo $JOB_DATA_RAW | jq --arg JOBNAME "$JOB_NAME" '.job_name = $JOBNAME')
# Write the modified data to a file
echo $JOB_DATA_RAW > /tmp/sumologic-logs/job-collector.json
curl -s -X POST -T /tmp/sumologic-logs/job-collector.json $JOB_HTTP_SOURCE
###
fi
fi
echo "rerunning loop"
i="$((i+1))"
echo "increment loop to $i"
echo " ---------- "
echo
done
echo "Complete. You may now find your logs on Sumologic."
Jobs in Workflow: 0
Only a single job has been found in the workflow, indicating this reporter is the only job in the pipeline.
Please add other jobs to the Workflow you wish to collect data on to send to Sumologic
CircleCI received exit code 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment