Sugerencia
Este procedimiento es parte del curso que le muestra cómo crear un inicio rápido. Si aún no lo hiciste, consulta la introducción del curso.
Cada procedimiento de este curso se basa en el anterior, así que cerciorar de implementar su aplicación antes de continuar con este.
Las métricas son medidas agregadas derivadas del rendimiento y comportamiento del sistema. Si su producto es una base de datos, puede enviar métricas como utilización de CPU, utilización de memoria y consulta de rendimiento. Tenga en cuenta que las métricas generalmente solo se usan si desea limitar la cantidad de datos enviados a New Relic. Tenga en cuenta que muchas métricas, como la tasa de errores y el rendimiento, se pueden calcular agregando evento.
New Relic le ofrece una variedad de formas de instrumentar su aplicación para enviar métricas a nuestra APImétrica. En esta lección, enviará métrica desde su producto empleando nuestro kit de desarrollo de software (SDK) de telemetría.
Emplee nuestro SDK
Ofrecemos un SDK de telemetría de código abierto en varios de los lenguajes de programación más populares. Estos envían datos a nuestra API de ingesta de datos, incluida nuestra API métrica. De estos SDK de lenguajes, Python, Java, Node/TypeScript y Go funcionan con la API métrica.
En esta lección, aprenderá cómo instalar y usar el SDK de telemetría de Python para enviar métrica a New Relic.
Cambie al directorio send-metrics/flashDB del repositorio del curso.
$cd ../send-metrics/flashDBEmplee pip para instalar el paquete newrelic-telemetry-sdk .
$pip install newrelic-telemetry-sdkAlmacene su clave de licencia de New Relic en una variable de entorno llamada $NEW_RELIC_LICENSE_KEY.
$export NEW_RELIC_LICENSE_KEY=<YOUR_USER_KEY>Sugerencia
Puede encontrar su clave de licencia de New Relic en la configuración de su cuenta.
A continuación, se familiarizará con la lógica de la aplicación.
import osimport randomimport datetime
db = {}stats = { "read_response_times": [], "read_errors": 0, "read_count": 0, "create_response_times": [], "create_errors": 0, "create_count": 0, "update_response_times": [], "update_errors": 0, "update_count": 0, "delete_response_times": [], "delete_errors": 0, "delete_count": 0, "cache_hit": 0,}last_push = { "read": datetime.datetime.now(), "create": datetime.datetime.now(), "update": datetime.datetime.now(), "delete": datetime.datetime.now(),}
def read(key):
print(f"Reading...")
if random.randint(0, 30) > 10: stats["cache_hit"] += 1
stats["read_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["read_errors"] += 1 stats["read_count"] += 1 try_send("read")
def create(key, value):
print(f"Writing...")
db[key] = value stats["create_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["create_errors"] += 1 stats["create_count"] += 1 try_send("create")
def update(key, value):
print(f"Updating...")
db[key] = value stats["update_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["update_errors"] += 1 stats["update_count"] += 1 try_send("update")
def delete(key):
print(f"Deleting...")
db.pop(key, None) stats["delete_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["delete_errors"] += 1 stats["delete_count"] += 1 try_send("delete")
def try_send(type_):
print("try_send")
def clear(type_): stats[f"{type_}_response_times"] = [] stats[f"{type_}_errors"] = 0 stats["cache_hit"] = 0 stats[f"{type_}_count"] = 0 last_push[type_] = datetime.datetime.now()Familiarízate con la aplicación.
Abra el archivo db.py en el IDE de su elección y familiarizar con la lógica de la aplicación.
Esta demostración emplea una aplicación Python ficticia que imita las operaciones Crear, Leer, Actualizar y Eliminar (CRUD).
import osimport randomimport datetime
db = {}stats = { "read_response_times": [], "read_errors": 0, "read_count": 0, "create_response_times": [], "create_errors": 0, "create_count": 0, "update_response_times": [], "update_errors": 0, "update_count": 0, "delete_response_times": [], "delete_errors": 0, "delete_count": 0, "cache_hit": 0,}last_push = { "read": datetime.datetime.now(), "create": datetime.datetime.now(), "update": datetime.datetime.now(), "delete": datetime.datetime.now(),}
def read(key):
print(f"Reading...")
if random.randint(0, 30) > 10: stats["cache_hit"] += 1
stats["read_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["read_errors"] += 1 stats["read_count"] += 1 try_send("read")
def create(key, value):
print(f"Writing...")
db[key] = value stats["create_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["create_errors"] += 1 stats["create_count"] += 1 try_send("create")
def update(key, value):
print(f"Updating...")
db[key] = value stats["update_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["update_errors"] += 1 stats["update_count"] += 1 try_send("update")
def delete(key):
print(f"Deleting...")
db.pop(key, None) stats["delete_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["delete_errors"] += 1 stats["delete_count"] += 1 try_send("delete")
def try_send(type_):
print("try_send")
def clear(type_): stats[f"{type_}_response_times"] = [] stats[f"{type_}_errors"] = 0 stats["cache_hit"] = 0 stats[f"{type_}_count"] = 0 last_push[type_] = datetime.datetime.now()Los read, create, update y delete son los métodos ficticios para imitar las operaciones CRUD. Para cada operación CRUD, stat respectivo se incrementa para reflejar que se realizó la operación. A continuación, envía estos stats datos a New Relic.
Enviar métrica a New Relic
Hay 3 tipos diferentes de métrica:
- GaugeMetric: envía un valor único en un único momento.
- CountMetric: rastrea el número total de ocurrencias de un evento.
- SummaryMetric: realiza un seguimiento de los valores de recuento, suma, mínimo y máximo a lo largo del tiempo.
A continuación, instrumente su aplicación para enviar estas métricas.
En db.py, configure el MetricClient.
import osimport randomimport datetime
from newrelic_telemetry_sdk import MetricClient
metric_client = MetricClient(os.environ["NEW_RELIC_LICENSE_KEY"])
db = {}stats = { "read_response_times": [], "read_errors": 0, "read_count": 0, "create_response_times": [], "create_errors": 0, "create_count": 0, "update_response_times": [], "update_errors": 0, "update_count": 0, "delete_response_times": [], "delete_errors": 0, "delete_count": 0, "cache_hit": 0,}last_push = { "read": datetime.datetime.now(), "create": datetime.datetime.now(), "update": datetime.datetime.now(), "delete": datetime.datetime.now(),}
def read(key):
print(f"Reading...")
if random.randint(0, 30) > 10: stats["cache_hit"] += 1
stats["read_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["read_errors"] += 1 stats["read_count"] += 1 try_send("read")
def create(key, value):
print(f"Writing...")
db[key] = value stats["create_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["create_errors"] += 1 stats["create_count"] += 1 try_send("create")
def update(key, value):
print(f"Updating...")
db[key] = value stats["update_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["update_errors"] += 1 stats["update_count"] += 1 try_send("update")
def delete(key):
print(f"Deleting...")
db.pop(key, None) stats["delete_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["delete_errors"] += 1 stats["delete_count"] += 1 try_send("delete")
def try_send(type_):
print("try_send")
def clear(type_): stats[f"{type_}_response_times"] = [] stats[f"{type_}_errors"] = 0 stats["cache_hit"] = 0 stats[f"{type_}_count"] = 0 last_push[type_] = datetime.datetime.now()Instrumenta tu aplicación para enviar la siguiente métrica a New Relic:
keysdb_sizeerrorscache_hitsresponse_timesimport osimport randomimport datetimefrom sys import getsizeoffrom newrelic_telemetry_sdk import MetricClient, GaugeMetric, CountMetric, SummaryMetricmetric_client = MetricClient(os.environ["NEW_RELIC_LICENSE_KEY"])db = {}stats = {"read_response_times": [],"read_errors": 0,"read_count": 0,"create_response_times": [],"create_errors": 0,"create_count": 0,"update_response_times": [],"update_errors": 0,"update_count": 0,"delete_response_times": [],"delete_errors": 0,"delete_count": 0,"cache_hit": 0,}last_push = {"read": datetime.datetime.now(),"create": datetime.datetime.now(),"update": datetime.datetime.now(),"delete": datetime.datetime.now(),}def read(key):print(f"Reading...")if random.randint(0, 30) > 10:stats["cache_hit"] += 1stats["read_response_times"].append(random.uniform(0.5, 1.0))if random.choice([True, False]):stats["read_errors"] += 1stats["read_count"] += 1try_send("read")def create(key, value):print(f"Writing...")db[key] = valuestats["create_response_times"].append(random.uniform(0.5, 1.0))if random.choice([True, False]):stats["create_errors"] += 1stats["create_count"] += 1try_send("create")def update(key, value):print(f"Updating...")db[key] = valuestats["update_response_times"].append(random.uniform(0.5, 1.0))if random.choice([True, False]):stats["update_errors"] += 1stats["update_count"] += 1try_send("update")def delete(key):print(f"Deleting...")db.pop(key, None)stats["delete_response_times"].append(random.uniform(0.5, 1.0))if random.choice([True, False]):stats["delete_errors"] += 1stats["delete_count"] += 1try_send("delete")def try_send(type_):print("try_send")def send_metrics(type_, interval_ms):print("sending metrics...")keys = GaugeMetric("fdb_keys", len(db))db_size = GaugeMetric("fdb_size", getsizeof(db))errors = CountMetric(name=f"fdb_{type_}_errors",value=stats[f"{type_}_errors"],interval_ms=interval_ms)cache_hits = CountMetric(name=f"fdb_cache_hits",value=stats["cache_hit"],interval_ms=interval_ms)response_times = stats[f"{type_}_response_times"]response_time_summary = SummaryMetric(f"fdb_{type_}_responses",count=len(response_times),min=min(response_times),max=max(response_times),sum=sum(response_times),interval_ms=interval_ms,)batch = [keys, db_size, errors, cache_hits, response_time_summary]response = metric_client.send_batch(batch)response.raise_for_status()print("Sent metrics successfully!")clear(type_)def clear(type_):stats[f"{type_}_response_times"] = []stats[f"{type_}_errors"] = 0stats["cache_hit"] = 0stats[f"{type_}_count"] = 0last_push[type_] = datetime.datetime.now()db.pyAquí, configura su plataforma para usar
GaugeMetric,CountMetricySummaryMetricpara informar métricamente a New Relic.
Modifique el módulo try_send para enviar estas métricas cada 2 segundos.
import osimport randomimport datetimefrom sys import getsizeof
from newrelic_telemetry_sdk import MetricClient, GaugeMetric, CountMetric, SummaryMetric
metric_client = MetricClient(os.environ["NEW_RELIC_LICENSE_KEY"])
db = {}stats = { "read_response_times": [], "read_errors": 0, "read_count": 0, "create_response_times": [], "create_errors": 0, "create_count": 0, "update_response_times": [], "update_errors": 0, "update_count": 0, "delete_response_times": [], "delete_errors": 0, "delete_count": 0, "cache_hit": 0,}last_push = { "read": datetime.datetime.now(), "create": datetime.datetime.now(), "update": datetime.datetime.now(), "delete": datetime.datetime.now(),}
def read(key):
print(f"Reading...")
if random.randint(0, 30) > 10: stats["cache_hit"] += 1
stats["read_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["read_errors"] += 1 stats["read_count"] += 1 try_send("read")
def create(key, value):
print(f"Writing...")
db[key] = value stats["create_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["create_errors"] += 1 stats["create_count"] += 1 try_send("create")
def update(key, value):
print(f"Updating...")
db[key] = value stats["update_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["update_errors"] += 1 stats["update_count"] += 1 try_send("update")
def delete(key):
print(f"Deleting...")
db.pop(key, None) stats["delete_response_times"].append(random.uniform(0.5, 1.0)) if random.choice([True, False]): stats["delete_errors"] += 1 stats["delete_count"] += 1 try_send("delete")
def try_send(type_):
print("try_send")
now = datetime.datetime.now() interval_ms = (now - last_push[type_]).total_seconds() * 1000 if interval_ms >= 2000: send_metrics(type_, interval_ms)
def send_metrics(type_, interval_ms):
print("sending metrics...")
keys = GaugeMetric("fdb_keys", len(db)) db_size = GaugeMetric("fdb_size", getsizeof(db))
errors = CountMetric( name=f"fdb_{type_}_errors", value=stats[f"{type_}_errors"], interval_ms=interval_ms )
cache_hits = CountMetric( name=f"fdb_cache_hits", value=stats["cache_hit"], interval_ms=interval_ms )
response_times = stats[f"{type_}_response_times"] response_time_summary = SummaryMetric( f"fdb_{type_}_responses", count=len(response_times), min=min(response_times), max=max(response_times), sum=sum(response_times), interval_ms=interval_ms, )
batch = [keys, db_size, errors, cache_hits, response_time_summary] response = metric_client.send_batch(batch) response.raise_for_status() print("Sent metrics successfully!") clear(type_)
def clear(type_): stats[f"{type_}_response_times"] = [] stats[f"{type_}_errors"] = 0 stats["cache_hit"] = 0 stats[f"{type_}_count"] = 0 last_push[type_] = datetime.datetime.now()Tu plataforma ahora reportará todas las métricas configuradas cada 2 segundos.
Navegue hasta la raíz de su aplicación en build-a-quickstart-lab/send-metrics/flashDB.
Ejecute sus servicios para verificar que esté reportando métrica.
$python simulator.pyWriting...try_sendWriting...try_sendReading...try_sendReading...try_sendWriting...try_sendWriting...try_sendReading...sending metrics...Sent metrics successfully!Opciones alternativas
Si el SDK de idiomas no se ajusta a tus necesidades o quieres algo más personalizado para enviar métricas a New Relic, prueba una de nuestras otras opciones:
- Implementación manual: si nuestro SDK en su idioma preferido no es compatible con métrica, siempre puede instrumentar manualmente su propia biblioteca para realizar una solicitud POST a la New Relic Metric API.
- Datos de Prometheus: los datos de Prometheus se pueden enviar a New Relic de dos formas: escritura remota y OpenMetrics. En un nivel muy alto, deberías usar escritura remota si gestionas tus propios servidores Prometheus y OpenMetrics si no lo haces.
En este procedimiento, instrumentaste tu servicio para enviar métrica a New Relic. A continuación, úselo para enviar evento.
Sugerencia
Este procedimiento es parte del curso que le muestra cómo crear un inicio rápido. Continúe con la siguiente lección, envíe el evento desde su producto.