update
This commit is contained in:
parent
e46e8ab3ea
commit
447a76b3cc
12 changed files with 101 additions and 83 deletions
|
|
@ -51,3 +51,12 @@ jobs:
|
|||
${{ steps.meta.outputs.latest_tag }}
|
||||
cache-from: type=registry,ref=${{ steps.meta.outputs.cache_tag }}
|
||||
cache-to: type=registry,ref=${{ steps.meta.outputs.cache_tag }},mode=max
|
||||
|
||||
- name: Update deployment image tag
|
||||
run: |
|
||||
sed -i "s|image: git\.mcintire\.me/graham/aprs\.me:.*|image: ${{ steps.meta.outputs.tag }}|g" k8s/deployment.yaml
|
||||
git config user.email "ci@git.mcintire.me"
|
||||
git config user.name "CI"
|
||||
git add k8s/deployment.yaml
|
||||
git diff --cached --quiet || git commit -m "chore: update aprs.me image to ${{ steps.meta.outputs.tag }} [skip ci]"
|
||||
git push origin HEAD:main
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[
|
||||
import_deps: [:ecto, :ecto_sql, :phoenix, :stream_data],
|
||||
import_deps: [:ecto, :ecto_sql, :phoenix],
|
||||
subdirectories: ["priv/*/migrations"],
|
||||
plugins: [Phoenix.LiveView.HTMLFormatter, Styler],
|
||||
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"],
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -35,6 +35,7 @@ npm-debug.log
|
|||
|
||||
/.lexical
|
||||
/badpackets.txt
|
||||
/packets.txt
|
||||
|
||||
# Ignore Kubernetes secrets file
|
||||
k8s/secrets.yaml
|
||||
|
|
|
|||
86
capture_aprs.py
Executable file
86
capture_aprs.py
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Connect to dallas.aprs2.net APRS-IS server and write all packets to packets.txt.
|
||||
Uses receive-only login (passcode -1) so no amateur license required.
|
||||
"""
|
||||
|
||||
import socket
|
||||
import sys
|
||||
import signal
|
||||
from datetime import datetime
|
||||
|
||||
HOST = "dallas.aprs2.net"
|
||||
PORT = 10152 # Full feed, no filter required (use 14580 with a filter)
|
||||
OUTPUT_FILE = "packets.txt"
|
||||
|
||||
running = True
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
global running
|
||||
print("\nShutting down...")
|
||||
running = False
|
||||
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
|
||||
def main():
|
||||
print(f"Connecting to {HOST}:{PORT}...")
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.connect((HOST, PORT))
|
||||
sock.settimeout(30)
|
||||
|
||||
f = sock.makefile("r", encoding="utf-8", errors="replace")
|
||||
|
||||
# Read server banner
|
||||
banner = f.readline().strip()
|
||||
print(f"Server: {banner}")
|
||||
|
||||
# Login - passcode -1 for receive-only
|
||||
login = "user N0CALL pass -1 vers APRSCapture 1.0\r\n"
|
||||
sock.sendall(login.encode())
|
||||
|
||||
# Read login response
|
||||
response = f.readline().strip()
|
||||
print(f"Login: {response}")
|
||||
|
||||
print(f"Writing packets to {OUTPUT_FILE} (Ctrl+C to stop)...")
|
||||
|
||||
count = 0
|
||||
with open(OUTPUT_FILE, "w", encoding="utf-8") as out:
|
||||
out.write(f"# APRS capture from {HOST}:{PORT}\n")
|
||||
out.write(f"# Started: {datetime.utcnow().isoformat()}Z\n\n")
|
||||
|
||||
while running:
|
||||
try:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
print("Connection closed by server.")
|
||||
break
|
||||
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Skip comments (server messages start with #)
|
||||
out.write(line + "\n")
|
||||
out.flush()
|
||||
count += 1
|
||||
|
||||
if count % 100 == 0:
|
||||
print(f" {count} packets captured...")
|
||||
|
||||
except socket.timeout:
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
break
|
||||
|
||||
print(f"Done. Captured {count} packets to {OUTPUT_FILE}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -37,9 +37,6 @@ config :aprsme, AprsmeWeb.Endpoint,
|
|||
secret_key_base: "IV9+ENaw9i8xjReRk4sULRvRgsmFVTGQwQGGrf4G+Q/SFMeHBCNWRlPXQ2YvT36R",
|
||||
server: true
|
||||
|
||||
# Disable Prometheus telemetry in test mode to avoid port conflicts
|
||||
config :aprsme, AprsmeWeb.Telemetry, enabled: false
|
||||
|
||||
# Disable cleanup scheduler in test environment
|
||||
config :aprsme, :cleanup_scheduler, enabled: false
|
||||
|
||||
|
|
|
|||
|
|
@ -96,17 +96,6 @@ This document tracks potential improvements identified during the multi-replica
|
|||
- Info page (/info/:callsign) now updates in real-time with complete packet data
|
||||
- Ensures all UI elements refresh properly when new packets arrive
|
||||
|
||||
### 3. Add Metrics and Monitoring with Prometheus
|
||||
- **Status**: Pending
|
||||
- **Impact**: High - Production visibility
|
||||
- **Details**:
|
||||
- Add Prometheus metrics exporter (prometheus_ex)
|
||||
- Track packet processing rates and latencies
|
||||
- Monitor connection pool usage (PgBouncer & app)
|
||||
- Track cache hit rates
|
||||
- Add custom business metrics
|
||||
- Monitor APRS-IS connection stability
|
||||
|
||||
## Medium Priority
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: aprs-me
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: aprs-me
|
||||
filterTags:
|
||||
pattern: '^main-(?P<ts>[0-9]+)-[a-f0-9]+$'
|
||||
extract: '$ts'
|
||||
policy:
|
||||
numerical:
|
||||
order: asc
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: aprs-me
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: git.mcintire.me/graham/aprs.me
|
||||
interval: 1m
|
||||
secretRef:
|
||||
name: forgejo-registry
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageUpdateAutomation
|
||||
metadata:
|
||||
name: aprs-me
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 1m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: aprs-me
|
||||
git:
|
||||
checkout:
|
||||
ref:
|
||||
branch: main
|
||||
push:
|
||||
branch: main
|
||||
commit:
|
||||
author:
|
||||
name: FluxCD
|
||||
email: fluxcd@aprs.me
|
||||
messageTemplate: 'chore: update aprs.me image to {{range .Changed.Changes}}{{.NewValue}}{{end}} [skip ci]'
|
||||
update:
|
||||
path: ./k8s
|
||||
strategy: Setters
|
||||
|
|
@ -12,23 +12,9 @@ defmodule AprsmeWeb.Telemetry do
|
|||
|
||||
@impl true
|
||||
def init(_arg) do
|
||||
children =
|
||||
if Application.get_env(:aprsme, AprsmeWeb.Telemetry)[:enabled] == false do
|
||||
[
|
||||
# Only telemetry poller in test mode
|
||||
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
|
||||
]
|
||||
|
||||
# Telemetry poller will execute the given period measurements
|
||||
# every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics
|
||||
else
|
||||
[
|
||||
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000},
|
||||
# Add reporters as children of your supervision tree.
|
||||
# {Telemetry.Metrics.ConsoleReporter, metrics: metrics()}
|
||||
{TelemetryMetricsPrometheus, [metrics: metrics()]}
|
||||
]
|
||||
end
|
||||
children = [
|
||||
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
|
||||
]
|
||||
|
||||
Supervisor.init(children, strategy: :one_for_one)
|
||||
end
|
||||
|
|
|
|||
3
mix.exs
3
mix.exs
|
|
@ -81,7 +81,6 @@ defmodule Aprsme.MixProject do
|
|||
{:resend, "~> 0.4.1"},
|
||||
{:telemetry_metrics, "~> 1.0"},
|
||||
{:telemetry_poller, "~> 1.0"},
|
||||
{:telemetry_metrics_prometheus, "~> 1.1"},
|
||||
aprs_dep(),
|
||||
{:esbuild, "~> 0.9", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.4.0", runtime: Mix.env() == :dev},
|
||||
|
|
@ -101,7 +100,7 @@ defmodule Aprsme.MixProject do
|
|||
{:stream_data, "~> 1.2.0", only: [:dev, :test]},
|
||||
{:igniter, "~> 0.7.0", only: [:dev, :test]},
|
||||
{:mox, "~> 1.2", only: :test},
|
||||
{:styler, "~> 1.10.0", only: [:dev, :test], runtime: false},
|
||||
{:styler, "~> 1.10", only: :dev, runtime: false},
|
||||
# {:httpoison, "~> 1.8"},
|
||||
{:hammer, "~> 7.0"},
|
||||
{:cachex, "~> 4.1"},
|
||||
|
|
|
|||
1
mix.lock
1
mix.lock
|
|
@ -104,7 +104,6 @@
|
|||
"tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"},
|
||||
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
|
||||
"telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"},
|
||||
"telemetry_metrics_prometheus": {:hex, :telemetry_metrics_prometheus, "1.1.0", "1cc23e932c1ef9aa3b91db257ead31ea58d53229d407e059b29bb962c1505a13", [:mix], [{:plug_cowboy, "~> 2.1", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.0", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}], "hexpm", "d43b3659b3244da44fe0275b717701542365d4519b79d9ce895b9719c1ce4d26"},
|
||||
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.2.1", "c9755987d7b959b557084e6990990cb96a50d6482c683fb9622a63837f3cd3d8", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5e2c599da4983c4f88a33e9571f1458bf98b0cf6ba930f1dc3a6e8cf45d5afb6"},
|
||||
"telemetry_poller": {:hex, :telemetry_poller, "1.3.0", "d5c46420126b5ac2d72bc6580fb4f537d35e851cc0f8dbd571acf6d6e10f5ec7", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "51f18bed7128544a50f75897db9974436ea9bfba560420b646af27a9a9b35211"},
|
||||
"tesla": {:hex, :tesla, "1.14.0", "2abcc2a5cf45b9b351f0dd3a03d2a1511cc25bb6000b5c65def9093e0535a9d7", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:mox, "~> 1.0", [hex: :mox, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "1c5a8575fb1d990100f016fe0bae70a0902ce01dec5fc693f694d09161142e18"},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue