for MPP-3467: add googlecloudprofiler to PrivateRelayConfig.ready

Also moves get_version_info to privaterelay.apps
This commit is contained in:
groovecoder 2024-01-17 15:31:36 -06:00
Родитель 1fdb597b37
Коммит 24187e0160
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4825AB58E974B712
8 изменённых файлов: 87 добавлений и 1 удалений

Просмотреть файл

@ -4,6 +4,7 @@ FXA_PROFILE_ENDPOINT=https://profile.stage.mozaws.net/v1
FXA_BASE_ORIGIN=https://accounts.stage.mozaws.net
FXA_ACCOUNTS_ENDPOINT=https://api-accounts.stage.mozaws.net/v1
GOOGLE_ANALYTICS_ID="UA-77033033-33"
GOOGLE_APPLICATION_CREDENTIALS=
BASKET_ORIGIN="https://basket-dev.allizom.org"
SECRET_KEY=unsafe-secret-key-for-dev-envs
ADMIN_ENABLED=

4
.gitignore поставляемый
Просмотреть файл

@ -16,4 +16,6 @@ junit.xml
state.json
har/
allure-results/
allure-report/
allure-report/
gcp_key.json
version.json

3
.profile Normal file
Просмотреть файл

@ -0,0 +1,3 @@
#!/bin/bash
# Heroku-only file to copy env var credentials to gcp_key.json file
echo "${GOOGLE_CREDENTIALS_B64}" | base64 -d > gcp_key.json

35
docs/profiler.md Normal file
Просмотреть файл

@ -0,0 +1,35 @@
# Profiler
This doc describes how we profile Relay code.
## Google Cloud Profiler
We use Google Cloud Profiler: https://cloud.google.com/profiler/docs/about-profiler
### Setup
Our google cloud profiler agent uses a service account with `roles/cloudprofiler.agent`
role. So, you need a JSON key file for the account, and you need to set the
`GOOGLE_APPLICATION_CREDENTIALS` environment variable to the fully qualified name of the
JSON key file.
#### Local servers
1. Get the JSON key file from another Relay ENGR
2. Update your `.env` `GOOGLE_APPLICATION_CREDENTIALS` value to the fully-qualified name
of the JSON key file.
#### Dev server
For the dev server, we use a `.profile` (and/or `bin/pre_compile`) script which copies
the `GOOGLE_CREDENTIALS_B64` environment variable value into a `gcp_key.json` file at
build time.
#### Stage & Prod
TBD: Figure out if we should use Compute Engine, GKE, Flexible Environment, or Standard
Environment instructions from https://cloud.google.com/profiler/docs/profiling-python#using-profiler
### Viewing profiler data
Go to https://console.cloud.google.com/profiler/fxprivaterelay-nonprod/cpu?project=moz-fx-fxprivate-nonprod-6df0

Просмотреть файл

@ -1,3 +1,5 @@
import json
from pathlib import Path
from typing import Any
import requests
import os
@ -10,10 +12,48 @@ from django.utils.functional import cached_property
ROOT_DIR = os.path.abspath(os.curdir)
def get_profiler_startup_data() -> tuple[str | None, str | None]:
from .utils import get_version_info
if settings.RELAY_CHANNEL not in ("dev", "stage", "prod"):
return (None, None)
if settings.RELAY_CHANNEL in ("dev", "stage"):
service = f"fxprivaterelay-{settings.RELAY_CHANNEL}"
if settings.RELAY_CHANNEL == "prod":
service = "fxprivaterelay"
version_info = get_version_info()
version = version_info.get("version", "unknown")
return service, version
class PrivateRelayConfig(AppConfig):
name = "privaterelay"
def ready(self) -> None:
if settings.GOOGLE_APPLICATION_CREDENTIALS is not None:
# Set up Google Cloud Profiler
service, version = get_profiler_startup_data()
if service != None:
import googlecloudprofiler
# Make sure the expect gcp_key.json file exists
gcp_key_json_path = Path(settings.GOOGLE_APPLICATION_CREDENTIALS)
if gcp_key_json_path.exists():
with gcp_key_json_path.open() as gcp_key_file:
try:
# Make sure the expect gcp_key.json file is valid json
gcp_key_data = json.load(gcp_key_file)
googlecloudprofiler.start(
service=service,
service_version=version,
project_id=gcp_key_data["project_id"],
)
except ValueError:
print(f"error during json.load({gcp_key_json_path})")
import privaterelay.signals
assert privaterelay.signals # Suppress "imported but unused" warnings

Просмотреть файл

@ -183,6 +183,9 @@ AWS_SQS_QUEUE_URL = config("AWS_SQS_QUEUE_URL", None)
RELAY_FROM_ADDRESS: str | None = config("RELAY_FROM_ADDRESS", None)
GOOGLE_ANALYTICS_ID = config("GOOGLE_ANALYTICS_ID", None)
GOOGLE_APPLICATION_CREDENTIALS: str | None = config(
"GOOGLE_APPLICATION_CREDENTIALS", None
)
INCLUDE_VPN_BANNER = config("INCLUDE_VPN_BANNER", False, cast=bool)
RECRUITMENT_BANNER_LINK = config("RECRUITMENT_BANNER_LINK", None)
RECRUITMENT_BANNER_TEXT = config("RECRUITMENT_BANNER_TEXT", None)

Просмотреть файл

@ -35,6 +35,7 @@ module = [
"django_ftl",
"django_ftl.bundles",
"google_measurement_protocol",
"googlecloudprofiler",
"jwcrypto",
"jwcrypto.jwe",
"jwcrypto.jwk",

Просмотреть файл

@ -17,6 +17,7 @@ dockerflow==2024.1.0
drf-spectacular==0.27.1
drf-spectacular-sidecar==2024.1.1
google-measurement-protocol==1.1.0
google-cloud-profiler==4.1.0
gunicorn==21.2.0
jwcrypto==1.5.1
markus[datadog]==4.2.0