Browse Source

feat(stats): send stats to the LinuxGSM usage collector (#5198)

* feat(stats): send stats to the LinuxGSM usage collector

Reports go to usage.linuxgsm.com once a day with a 5 second timeout instead of Google Analytics. The CPU model and machine ID are no longer sent. Alert type counts stay on Google Analytics until the collector accepts them. Fixes #5197

* Send enabled alert types to the usage collector and stop calling Google

The daily report gains an alerts list (names only, never addresses or tokens). The per-alert Google Analytics POSTs, which also ran on every invocation, are removed so the script no longer contacts Google.
Daniel Gibbs 14 giờ trước cách đây
mục cha
commit
17452ee3c3
1 tập tin đã thay đổi với 60 bổ sung và 131 xóa
  1. 60 131
      lgsm/modules/info_stats.sh

+ 60 - 131
lgsm/modules/info_stats.sh

@@ -4,7 +4,6 @@
 # Contributors: https://linuxgsm.com/contrib
 # Contributors: https://linuxgsm.com/contrib
 # Website: https://linuxgsm.com
 # Website: https://linuxgsm.com
 # Description: Collect optional Stats sent to LinuxGSM project.
 # Description: Collect optional Stats sent to LinuxGSM project.
-# Uses Google analytics.
 
 
 moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
 moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
 
 
@@ -47,140 +46,70 @@ fi
 
 
 uuidinstance=$(cat "${datadir}/uuid-${selfname}.txt")
 uuidinstance=$(cat "${datadir}/uuid-${selfname}.txt")
 uuidinstall=$(cat "${datadir}/uuid-install.txt")
 uuidinstall=$(cat "${datadir}/uuid-install.txt")
-# machine-id is a unique id set on OS install
-uuidhardware=$(cat "/etc/machine-id")
+uuidreport="${uuidinstance##*_}"
 
 
-# results are rounded up to reduce number of different results in analytics.
+# results are rounded up to reduce number of different results.
 # nearest 100Mhz.
 # nearest 100Mhz.
 cpuusedmhzroundup="$(((cpuusedmhz + 99) / 100 * 100))"
 cpuusedmhzroundup="$(((cpuusedmhz + 99) / 100 * 100))"
 # nearest 100MB
 # nearest 100MB
 memusedmbroundup="$(((memusedmb + 99) / 100 * 100))"
 memusedmbroundup="$(((memusedmb + 99) / 100 * 100))"
 
 
-# Convert any commas to dots.
-physmemtotal="${physmemtotal//,/.}"
-
-apisecret="A-OzP02TSMWt4_vHi6ZpUw"
-measurementid="G-0CR8V7EMT5"
-
-# Sending stats to Google Analytics GA4
-payload="{
-	\"client_id\": \"${uuidinstance}\",
-	\"events\": [
-		{
-		\"name\": \"LinuxGSM\",
-		\"params\": {
-			\"cpuusedmhzroundup\": \"${cpuusedmhzroundup}\",
-			\"diskused\": \"${serverfilesdu}\",
-			\"distro\": \"${distroname}\",
-			\"game\": \"${gamename}\",
-			\"memusedmbroundup\": \"${memusedmbroundup}\",
-			\"ramused\": \"${memusedmbroundup}\",
-			\"servercpu\": \"${cpumodel} ${cpucores} cores\",
-			\"servercpufreq\": \"${cpufreqency} x${cpulogicalcores}\",
-			\"servercpuphysicalcores\": \"${cpuphysicalcoresdisplay}\",
-			\"servercpulogicalcpus\": \"${cpulogicalcores}\",
-			\"servercpufreqrange\": \"${cpufrequencydisplay}\",
-			\"serverdisk\": \"${totalspace}\",
-			\"serverfilesdu\": \"${serverfilesdu}\",
-			\"serverram\": \"${physmemtotal}\",
-			\"serverramgb\": \"${physmemtotalgb}\",
-			\"uuidhardware\": \"${uuidhardware}\",
-			\"uuidinstall\": \"${uuidinstall}\",
-			\"uuidinstance\": \"${uuidinstance}\",
-			\"version\": \"${version}\",
-			\"virtualenvironment\": \"${virtualenvironment}\",
-			\"tmuxversion\": \"${tmuxversion}\",
-			\"java\": \"${javaversion}\"
-			}
-		}
-	]
-}"
-
-fn_alert_payload() {
-	alertpayload="{
-	\"client_id\": \"${uuidinstance}\",
-	\"events\": [
-		{
-		\"name\": \"LinuxGSM\",
-		\"params\": {
-			\"alert\": \"${alerttype}\"
-			}
-		}
-	]
-}"
-}
-
-curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=A-OzP02TSMWt4_vHi6ZpUw&measurement_id=G-0CR8V7EMT5" -H "Content-Type: application/json" -d "${payload}"
-
-if [ "${discordalert}" == "on" ]; then
-	alerttype="discord"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${emailalert}" == "on" ]; then
-	alerttype="email"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${gotifyalert}" == "on" ]; then
-	alerttype="gotify"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${iftttalert}" == "on" ]; then
-	alerttype="ifttt"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${matrixalert}" == "on" ]; then
-	alerttype="matrix"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${ntfyalert}" == "on" ]; then
-	alerttype="ntfy"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${pushbulletalert}" == "on" ]; then
-	alerttype="pushbullet"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${pushoveralert}" == "on" ]; then
-	alerttype="pushover"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${rocketchatalert}" == "on" ]; then
-	alerttype="rocketchat"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${slackalert}" == "on" ]; then
-	alerttype="slack"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
-if [ "${telegramalert}" == "on" ]; then
-	alerttype="telegram"
-	fn_alert_payload
-	curl -X POST "https://www.google-analytics.com/mp/collect?api_secret=${apisecret}&measurement_id=${measurementid}" -H "Content-Type: application/json" -d "${alertpayload}"
-fi
+statsdate="$(date -u +%F)"
+statsstamp="${datadir}/stats-last-sent-${selfname}"
+
+if [ "$(cat "${statsstamp}" 2> /dev/null)" != "${statsdate}" ] && [ "$(command -v jq 2> /dev/null)" ]; then
+	echo "${statsdate}" > "${statsstamp}"
 
 
-fn_script_log_info "Send LinuxGSM stats"
-fn_script_log_info "* uuid-${selfname}: ${uuidinstance}"
-fn_script_log_info "* uuid-install: ${uuidinstall}"
-fn_script_log_info "* uuid-hardware: ${uuidhardware}"
-fn_script_log_info "* Game Name: ${gamename}"
-fn_script_log_info "* Distro Name: ${distroname}"
-fn_script_log_info "* Game Server CPU Used: ${cpuusedmhzroundup}MHz"
-fn_script_log_info "* Game Server RAM Used: ${memusedmbroundup}MB"
-fn_script_log_info "* Game Server Disk Used: ${serverfilesdu}"
-fn_script_log_info "* Server CPU Model: ${cpumodel}"
-fn_script_log_info "* Server CPU Average Frequency: ${cpufreqency}"
-fn_script_log_info "* Server RAM: ${physmemtotal}"
-fn_script_log_info "* Server Disk: ${totalspace}"
-fn_script_log_info "* Virtual Environment: ${virtualenvironment}"
-fn_script_log_info "* LinuxGSM Version: ${version}"
-fn_script_log_info "* Enabled Alerts"
+	statscores="${cpucores}"
+	if [[ ! "${statscores}" =~ ^[0-9]+$ ]]; then
+		statscores="${cpulogicalcores}"
+	fi
+	statsramgb="$(awk -v mb="${physmemtotalmb}" 'BEGIN{printf "%.1f", mb / 1024}')"
+	statsdiskgb="$(LC_ALL=C df -BG -P "${rootdir}" 2> /dev/null | awk 'NR==2{gsub("G","",$2); print $2}')"
+	statsfilesgb="$(awk -v v="${serverfilesdu}" 'BEGIN{n=v+0; u=substr(v,length(v)); if(u=="K")n/=1048576; else if(u=="M")n/=1024; else if(u=="T")n*=1024; printf "%.2f", n}')"
+
+	statsalerts=""
+	for statsalerttype in discord email gotify ifttt matrix ntfy pushbullet pushover rocketchat slack telegram; do
+		statsalertvar="${statsalerttype}alert"
+		if [ "${!statsalertvar}" == "on" ]; then
+			statsalerts+="${statsalerttype} "
+		fi
+	done
+
+	statspayload="$(jq -cn \
+		--arg uuid "${uuidreport}" \
+		--arg game "${gamename}" \
+		--arg distro "${distroname}" \
+		--arg version "${version}" \
+		--arg virt "${virtualenvironment}" \
+		--arg cores "${statscores}" \
+		--arg ram "${statsramgb}" \
+		--arg disk "${statsdiskgb}" \
+		--arg ramused "${memusedmbroundup}" \
+		--arg cpuused "${cpuusedmhzroundup}" \
+		--arg filesgb "${statsfilesgb}" \
+		--arg alerts "${statsalerts}" \
+		'{uuid: $uuid, game: $game, distro: $distro, version: $version, virt: $virt, cpu_cores: ($cores | tonumber? // 0), ram_gb: ($ram | tonumber? // 0), disk_gb: ($disk | tonumber? // 0)}
+		+ (if ($ramused | tonumber? // 0) > 0 then {ram_used_mb: ($ramused | tonumber)} else {} end)
+		+ (if ($cpuused | tonumber? // 0) > 0 then {cpu_used_mhz: ($cpuused | tonumber)} else {} end)
+		+ (if ($filesgb | tonumber? // 0) > 0 then {disk_used_gb: ($filesgb | tonumber)} else {} end)
+		+ (if ($alerts | length) > 0 then {alerts: ($alerts | split(" ") | map(select(length > 0)))} else {} end)' 2> /dev/null)"
+
+	if [ -n "${statspayload}" ]; then
+		curl -sS -f --max-time 5 -X POST "https://usage.linuxgsm.com/v1/report" -H "Content-Type: application/json" -d "${statspayload}" > /dev/null 2>&1
+	fi
+
+	fn_script_log_info "Send LinuxGSM stats"
+	fn_script_log_info "* uuid-${selfname}: ${uuidreport}"
+	fn_script_log_info "* Game Name: ${gamename}"
+	fn_script_log_info "* Distro Name: ${distroname}"
+	fn_script_log_info "* LinuxGSM Version: ${version}"
+	fn_script_log_info "* Virtual Environment: ${virtualenvironment}"
+	fn_script_log_info "* Game Server CPU Used: ${cpuusedmhzroundup}MHz"
+	fn_script_log_info "* Game Server RAM Used: ${memusedmbroundup}MB"
+	fn_script_log_info "* Game Server Disk Used: ${serverfilesdu}"
+	fn_script_log_info "* Server CPU Cores: ${statscores}"
+	fn_script_log_info "* Server RAM: ${statsramgb}GB"
+	fn_script_log_info "* Server Disk: ${statsdiskgb}GB"
+	fn_script_log_info "* Alerts: ${statsalerts:-none}"
+fi