mirror of
https://github.com/projecthorus/sondehub-infra.git
synced 2025-01-18 18:56:26 +00:00
add listener stats
This commit is contained in:
parent
a058f17464
commit
bfeda317bf
26
cdn.tf
26
cdn.tf
@ -544,6 +544,32 @@ resource "aws_cloudfront_distribution" "api" {
|
||||
target_origin_id = "Custom-api.${local.domain_name}"
|
||||
viewer_protocol_policy = "redirect-to-https"
|
||||
}
|
||||
ordered_cache_behavior {
|
||||
allowed_methods = ["GET", "HEAD"]
|
||||
cached_methods = [
|
||||
"HEAD",
|
||||
"GET"
|
||||
]
|
||||
compress = true
|
||||
default_ttl = 300
|
||||
forwarded_values {
|
||||
cookies {
|
||||
forward = "none"
|
||||
}
|
||||
headers = [
|
||||
"Origin",
|
||||
"Access-Control-Request-Method",
|
||||
"Access-Control-Request-Headers"
|
||||
]
|
||||
query_string = false
|
||||
}
|
||||
max_ttl = 300
|
||||
min_ttl = 300
|
||||
path_pattern = "listener/stats"
|
||||
smooth_streaming = false
|
||||
target_origin_id = "Custom-api.${local.domain_name}"
|
||||
viewer_protocol_policy = "redirect-to-https"
|
||||
}
|
||||
comment = ""
|
||||
price_class = "PriceClass_100"
|
||||
enabled = true
|
||||
|
@ -391,3 +391,96 @@ def get_sites(event, context):
|
||||
|
||||
|
||||
|
||||
def telm_stats(event, context):
|
||||
|
||||
path = "telm-*/_search"
|
||||
payload = {
|
||||
"aggs": {
|
||||
"software_name": {
|
||||
"terms": {
|
||||
"field": "software_name.keyword",
|
||||
"order": {
|
||||
"unique_callsigns": "desc"
|
||||
},
|
||||
"size": 10
|
||||
},
|
||||
"aggs": {
|
||||
"unique_callsigns": {
|
||||
"cardinality": {
|
||||
"field": "uploader_callsign.keyword"
|
||||
}
|
||||
},
|
||||
"software_version": {
|
||||
"terms": {
|
||||
"field": "software_version.keyword",
|
||||
"order": {
|
||||
"unique_callsigns": "desc"
|
||||
},
|
||||
"size": 10
|
||||
},
|
||||
"aggs": {
|
||||
"unique_callsigns": {
|
||||
"cardinality": {
|
||||
"field": "uploader_callsign.keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"size": 0,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [],
|
||||
"filter": [
|
||||
{
|
||||
"range": {
|
||||
"datetime": {
|
||||
"gte": "now-7d",
|
||||
"lte": "now",
|
||||
"format": "strict_date_optional_time"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = es.request(json.dumps(payload), path, "POST")
|
||||
output = {
|
||||
x['key']: {
|
||||
"telemetry_count": x["doc_count"],
|
||||
"unique_callsigns": x["unique_callsigns"]["value"],
|
||||
"versions": {
|
||||
y["key"]: {
|
||||
"telemetry_count": y["doc_count"],
|
||||
"unique_callsigns": y["unique_callsigns"]["value"]
|
||||
}
|
||||
for y in x['software_version']['buckets']
|
||||
}
|
||||
}
|
||||
for x in results['aggregations']['software_name']['buckets']
|
||||
}
|
||||
|
||||
compressed = BytesIO()
|
||||
with gzip.GzipFile(fileobj=compressed, mode='w') as f:
|
||||
json_response = json.dumps(output)
|
||||
f.write(json_response.encode('utf-8'))
|
||||
|
||||
gzippedResponse = compressed.getvalue()
|
||||
return {
|
||||
"body": base64.b64encode(gzippedResponse).decode(),
|
||||
"isBase64Encoded": True,
|
||||
"statusCode": 200,
|
||||
"headers": {
|
||||
"Content-Encoding": "gzip",
|
||||
"content-type": "application/json"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
from . import *
|
||||
|
||||
#print(get_listener_telemetry({"queryStringParameters":{}}, {}))
|
||||
print(get_sondes({
|
||||
print(telm_stats({
|
||||
"version": "2.0",
|
||||
"routeKey": "GET /sondes",
|
||||
"rawPath": "/sondes",
|
||||
|
47
query.tf
47
query.tf
@ -94,6 +94,28 @@ resource "aws_lambda_function" "get_listener_telemetry" {
|
||||
|
||||
|
||||
|
||||
resource "aws_lambda_function" "get_listener_stats" {
|
||||
function_name = "get_listener_stats"
|
||||
handler = "query.telm_stats"
|
||||
s3_bucket = aws_s3_bucket_object.lambda.bucket
|
||||
s3_key = aws_s3_bucket_object.lambda.key
|
||||
source_code_hash = data.archive_file.lambda.output_base64sha256
|
||||
publish = true
|
||||
memory_size = 256
|
||||
role = aws_iam_role.basic_lambda_role.arn
|
||||
runtime = "python3.9"
|
||||
timeout = 30
|
||||
architectures = ["arm64"]
|
||||
environment {
|
||||
variables = {
|
||||
"ES" = "es.${local.domain_name}"
|
||||
}
|
||||
}
|
||||
tags = {
|
||||
Name = "get_listener_stats"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
resource "aws_lambda_permission" "get_sondes" {
|
||||
@ -110,6 +132,12 @@ resource "aws_lambda_permission" "get_sites" {
|
||||
source_arn = "arn:aws:execute-api:us-east-1:${data.aws_caller_identity.current.account_id}:${aws_apigatewayv2_api.main.id}/*/*/sites"
|
||||
}
|
||||
|
||||
resource "aws_lambda_permission" "get_listener_stats" {
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = aws_lambda_function.get_listener_stats.arn
|
||||
principal = "apigateway.amazonaws.com"
|
||||
source_arn = "arn:aws:execute-api:us-east-1:${data.aws_caller_identity.current.account_id}:${aws_apigatewayv2_api.main.id}/*/*/listener/stats"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -143,6 +171,14 @@ resource "aws_apigatewayv2_route" "get_sites" {
|
||||
}
|
||||
|
||||
|
||||
resource "aws_apigatewayv2_route" "get_listener_stats" {
|
||||
api_id = aws_apigatewayv2_api.main.id
|
||||
api_key_required = false
|
||||
authorization_type = "NONE"
|
||||
route_key = "GET /listener/stats"
|
||||
target = "integrations/${aws_apigatewayv2_integration.get_listener_stats.id}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -208,3 +244,14 @@ resource "aws_apigatewayv2_integration" "get_listener_telemetry" {
|
||||
payload_format_version = "2.0"
|
||||
}
|
||||
|
||||
resource "aws_apigatewayv2_integration" "get_listener_stats" {
|
||||
api_id = aws_apigatewayv2_api.main.id
|
||||
connection_type = "INTERNET"
|
||||
integration_method = "POST"
|
||||
integration_type = "AWS_PROXY"
|
||||
integration_uri = aws_lambda_function.get_listener_stats.arn
|
||||
timeout_milliseconds = 30000
|
||||
payload_format_version = "2.0"
|
||||
}
|
||||
|
||||
|
||||
|
26
swagger.yaml
26
swagger.yaml
@ -197,6 +197,18 @@ paths:
|
||||
description: Returns a dictionary keyed by uploader_callsign of a dictionary of times with listener data.
|
||||
schema:
|
||||
$ref: "#/definitions/listener"
|
||||
/listeners/stats:
|
||||
get:
|
||||
summary: Basic version stats
|
||||
description: >
|
||||
Use this to get stats on how many users are using specific software
|
||||
produces:
|
||||
- "application/json"
|
||||
responses:
|
||||
200:
|
||||
description: Returns a dictionary of softwares and versions
|
||||
schema:
|
||||
$ref: "#/definitions/listener_stats"
|
||||
/sondes/websocket:
|
||||
get:
|
||||
description: Gets a presigned URL for use in connecting to the MQTT websocket endpoint.
|
||||
@ -823,7 +835,19 @@ definitions:
|
||||
uploader_antenna:
|
||||
type: string
|
||||
description: Station antenna/receiver information, free-text string.
|
||||
|
||||
listener_stats:
|
||||
type: object
|
||||
additionalProperties:
|
||||
description: softwareName
|
||||
type: object
|
||||
example:
|
||||
radiosonde_auto_rx:
|
||||
telemetry_count: 500
|
||||
unique_callsigns: 10
|
||||
versions:
|
||||
"1.5.8":
|
||||
telemetry_count: 25463802
|
||||
unique_callsigns: 327
|
||||
listener:
|
||||
type: object
|
||||
properties:
|
||||
|
Loading…
Reference in New Issue
Block a user