From b763eecf242f82d9d5bae965836d470e253f4213 Mon Sep 17 00:00:00 2001
From: jcountsNR <94138069+jcountsNR@users.noreply.github.com>
Date: Wed, 2 Feb 2022 17:11:47 -0800
Subject: [PATCH] feat: added send data page
---
src/data/nav.yml | 8 +-
.../data-integration.mdx | 256 ------------------
.../instrument-library/index.mdx | 20 ++
.../instrument-library/send-events.mdx | 170 ++++++++++++
4 files changed, 196 insertions(+), 258 deletions(-)
delete mode 100644 src/markdown-pages/contribute-to-quickstarts/data-integration.mdx
create mode 100644 src/markdown-pages/contribute-to-quickstarts/instrument-library/index.mdx
create mode 100644 src/markdown-pages/contribute-to-quickstarts/instrument-library/send-events.mdx
diff --git a/src/data/nav.yml b/src/data/nav.yml
index e88c9e72d..65a5e83d3 100644
--- a/src/data/nav.yml
+++ b/src/data/nav.yml
@@ -194,8 +194,11 @@
icon: fe-zap
url: '/contribute-to-quickstarts'
pages:
- - title: Data Integration with the New Relic Event API
- url: '/contribute-to-quickstarts/data-integration'
+ - title: Instrument your library
+ url: '/contribute-to-quickstarts/instrument-library'
+ pages:
+ - title: Send Event Data
+ url: '/contribute-to-quickstarts/instrument-library/send-events'
- title: Build a quickstart
url: '/contribute-to-quickstarts/build-a-quickstart'
pages:
@@ -210,6 +213,7 @@
- title: Populate your alert configurations with NerdGraph
url: '/contribute-to-quickstarts/query-alerts-for-quickstart'
+
- title: Try our APIs
icon: nr-share
url: '/try-our-apis'
diff --git a/src/markdown-pages/contribute-to-quickstarts/data-integration.mdx b/src/markdown-pages/contribute-to-quickstarts/data-integration.mdx
deleted file mode 100644
index d0886ec5a..000000000
--- a/src/markdown-pages/contribute-to-quickstarts/data-integration.mdx
+++ /dev/null
@@ -1,256 +0,0 @@
----
-title: 'Data Integration with the New Relic Event API'
-template: 'GuideTemplate'
-description: 'With our Events API you can ingest your data as the first step towards your quickstart contribution.'
-tags:
- - quickstart
----
-
-
-
-The first step of submitting your own quickstart to the I/O catalog is to set up your data integration. Here, you will learn how to use New Relic's [Event API](https://docs.newrelic.com/docs/telemetry-data-platform/ingest-manage-data/ingest-apis/use-event-api-report-custom-events) to set up your data integration to use in your quickstart.
-We'll show how to a generate your event payload, as well as give an agentless curl command example, and code example in python of how to set up your data integration.
-
-
-
-
-## Generating JSON file
-
-First we'll discuss generating your JSON payload. Here are several key factors to keep in mind to format your data properly.
-
-
-1. **Required Field:** The JSON data must contain an 'eventType' key-value Pair. This will be used to describe your event type, and allow it to be queryable in New Relic. (see below example)
-2. **Data Types:** This API only accepts key-value pairs. This means that you cannot send map/object or array values in nested JSON to this API. If you are not able to format the JSON payload accordingly, try using our [Log API](https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/) instead.
-3. **Date and Time** Note that we use and unformatted Unix timestamp for our date/time fields. In order for your NRQL queries to read, format, compute duration, etc. on your timestamp fields, they must be in this format (otherwise they will be displayed as a string only).
-4. **JSON Payload example** Here is an example of a custom event JSON payload compatible with New Relic API's.
-
-```JSON
-[
- {
- "eventType":"Purchase",
- "account":3,
- "amount":259.54,
- "timestamp": 1642053958
- },
- {
- "eventType":"Purchase",
- "account":5,
- "amount":12309,
- "product":"Item"
- }
-]
-```
-
-
-
-Check our full [limits documentation](https://docs.newrelic.com/docs/data-apis/ingest-apis/introduction-event-api/#limits) to see a full list governor limits applied to the Event API.
-
-
-
-## Agentless Request using curl command
-
-Here we'll make an HTTPS POST request to the Event API using a curl command as well as a Windows/PowerShell example. You can apply this into your application using a webhook. Just ensure to set the YOUR_API_KEY variable, and allow your users to set that as a parameter.
-
-* Linux/Bash Example
-
-```bash
-gzip -c example_events.json | curl -X POST -H "Content-Type: application/json" -H "Api-Key: YOUR_API_KEY" -H "Content-Encoding: gzip" https://insights-collector.newrelic.com/v1/accounts/events --data-binary @-
-```
-* Windows/PowerShell example
-```bash
-# Setting the API Key Variable
-$insertkey = "YOUR_API_KEY"
-
-# Replace with your custom event for the body
-$body = '[{"eventType": "powershell", "account": 4, "amount": 123, "fileLocation": "c:\\temp2", "zipped": "true" }]'
-
-$headers = @{}
-$headers.Add("Api-Key", "$insertkey")
-$headers.Add("Content-Encoding", "gzip")
-
-
-$encoding = [System.Text.Encoding]::UTF8
-$enc_data = $encoding.GetBytes($body)
-
-$output = [System.IO.MemoryStream]::new()
-$gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
-
-$gzipStream.Write($enc_data, 0, $enc_data.Length)
-$gzipStream.Close()
-$gzipBody = $output.ToArray()
-
-Invoke-WebRequest -Headers $headers -Method Post -Body $gzipBody "https://insights-collector.newrelic.com/v1/accounts/events"
-```
-
-
-
-Always use compression with every payload. This allows you to send more data, and it saves resources during parsing.
-
-
-## Python POST Request Example
-
-Here is a practical example using python to set up a data integration. First, we'll set some key parameters and update the header.
-
-
-```Python
-
-
-class Client(object):
- """HTTP Client for interacting with New Relic APIs
-
- This class is used to send data to the New Relic APIs over HTTP. This class
- will automatically handle retries as needed.
-
- :param insert_key: Insights insert key
- :type insert_key: str
- :param host: (optional) Override the host for the client.
- :type host: str
- :param port: (optional) Override the port for the client.
- Default: 443
- :type port: int
-
- Usage::
-
- >>> import os
- >>> insert_key = os.environ.get("NEW_RELIC_INSERT_KEY", "")
- >>> client = Client(insert_key, host="metric-api.newrelic.com")
- >>> response = client.send({})
- >>> client.close()
- """
-
-
- )
-
- def __init__(insert_key, host=None, port=443):
- host = host or self.HOST
- headers = self.HEADERS.copy()
- headers.update(
- {
- "Api-Key": insert_key,
- "Content-Encoding": "gzip",
- "Content-Type": "application/json",
- }
- )
-
-```
-Next, we'll prepare the JSON payload.
-
-```Python
-
- @staticmethod
- def _compress_payload(payload):
- level = zlib.Z_DEFAULT_COMPRESSION
- compressor = zlib.compressobj(level, zlib.DEFLATED, 31)
- payload = compressor.compress(payload)
- payload += compressor.flush()
- return payload
-
- def _create_payload(self, items, common):
- payload = {self.PAYLOAD_TYPE: items}
- if common:
- payload["common"] = common
-
- payload = json.dumps([payload], separators=(",", ":"))
- if not isinstance(payload, bytes):
- payload = payload.encode("utf-8")
-
- return self._compress_payload(payload)
-
- def send(self, item):
- """Send a single item
-
- :param item: The object to send
- :type item: dict
-
- :rtype: HTTPResponse
- """
- return self.send_batch((item,))
-
- def send_batch(self, items, common=None):
- """Send a batch of items
-
- :param items: An iterable of items to send to New Relic.
- :type items: list or tuple
- :param common: (optional) A map of attributes that will be set on each
- item.
- :type common: dict
-
- :rtype: HTTPResponse
- """
- # Specifying the headers argument overrides any base headers existing
- # in the pool, so we must copy all existing headers
- headers = self._headers.copy()
-
- # Generate a unique request ID for this request
- headers["x-request-id"] = str(uuid.uuid4())
-
- payload = self._create_payload(items, common)
- return self._pool.urlopen("POST", self.PATH, body=payload, headers=headers)
-
-```
-
-Lastly, we'll make the HTTP POST Request.
-
-```Python
-
-class EventClient(Client):
- """HTTP Client for interacting with the New Relic Event API
-
- This class is used to send events to the New Relic Event API over HTTP.
-
- :param insert_key: Insights insert key
- :type insert_key: str
- :param host: (optional) Override the host for the event API
- endpoint.
- :type host: str
- :param port: (optional) Override the port for the client.
- Default: 443
- :type port: int
-
- Usage::
-
- >>> import os
- >>> insert_key = os.environ.get("NEW_RELIC_INSERT_KEY", "")
- >>> event_client = EventClient(insert_key)
- >>> response = event_client.send({})
- >>> event_client.close()
- """
-
- HOST = "insights-collector.newrelic.com"
- PATH = "/v1/accounts/events"
-
- def _create_payload(self, items, common):
- payload = json.dumps(items)
- if not isinstance(payload, bytes):
- payload = payload.encode("utf-8")
-
- return self._compress_payload(payload)
-
- def send_batch(self, items):
- """Send a batch of items
-
- :param items: An iterable of items to send to New Relic.
- :type items: list or tuple
-
- :rtype: HTTPResponse
- """
- return super(EventClient, self).send_batch(items, None)
-
-
-```
-
-
-
-For more information about our telemetry SDKs, including complete code examples, check out our [available libraries](https://docs.newrelic.com/docs/data-apis/ingest-apis/telemetry-sdks-report-custom-telemetry-data/#client-libraries).
-
-
-
-## Summary
-
-In this guide, you learned how to integrate your data into the New Relic platform using our metric API. You should now see your custom event data being populated in your New Relic Account in [NR1](https://one.newrelic.com/launcher). Continue to the next step to start using that data and creating a dashboard.
-
-
-
-This procedure is the first step of creating your new quickstart. To continue your progression, jump to the next procedure: [create a dashboard](/contribute-to-quickstarts/build-a-quickstart/create-a-dashboard).
-
-
diff --git a/src/markdown-pages/contribute-to-quickstarts/instrument-library/index.mdx b/src/markdown-pages/contribute-to-quickstarts/instrument-library/index.mdx
new file mode 100644
index 000000000..faacbfb0f
--- /dev/null
+++ b/src/markdown-pages/contribute-to-quickstarts/instrument-library/index.mdx
@@ -0,0 +1,20 @@
+---
+title: 'Instrument your Library'
+template: 'OverviewTemplate'
+description: ''
+---
+
+If your looking to jump into building your own quickstart, the first step is instrumenting your own library to send data to New Relic. New Relic I/O gives end users the ability to slice and dice observability data around their application, server, etc. Setting up your library to get data into New Relic is critical to this process, so that the end users have a streamlined click-thorugh experience to see your data on our platform. You will need to instrument your library with at least one data type to be able to observe it via a dashboard or alert.
+
+
+## Observability Data Options
+
+ New Relic has [four types of observability data](https://docs.newrelic.com/docs/data-apis/understand-data/new-relic-data-types) which we call MELT data; *Metrics, Events, Logs, and Traces*. Each one handles a specific use case, so you'll have to decide which one fits your needs best.
+
+ Here is some context to help you decide:
+
+ - [Events](contribute-to-quickstarts/create-a-quickstart/instrument-library/send-events) **(Most Common)**: Events are used if you are capturing something occuring in your application, server, library, etc. For CI/CD applications this might be a capture of each time a job runs. For security applications this might be any time a threat is detected.
+ - [Logs](https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/) **(Common)**: Logs should be used if your library uses multiple attributes (ie. nested key-value data), or if your library is set up already to use log drains.
+ - [Metrics](https://docs.newrelic.com/docs/data-apis/ingest-apis/metric-api/introduction-metric-api/) **(Uncommon)**: Metrics are generally collected as aggregated data or as a numeric status at a point in time. Most metrics can be sent or aggregated through events, which is why we recommend events instead. You might want to use metrics if you view the data at a very high level, and don't expect your users to need a more detailed analysis.
+ - [Traces](https://docs.newrelic.com/docs/distributed-tracing/trace-api/introduction-trace-api/) **(Uncommon)**: Traces should be used if you have your own tool that tracks tracing, and you want to instrument that into new relic.
+
diff --git a/src/markdown-pages/contribute-to-quickstarts/instrument-library/send-events.mdx b/src/markdown-pages/contribute-to-quickstarts/instrument-library/send-events.mdx
new file mode 100644
index 000000000..ca10928b6
--- /dev/null
+++ b/src/markdown-pages/contribute-to-quickstarts/instrument-library/send-events.mdx
@@ -0,0 +1,170 @@
+---
+title: 'Send Events from Your Library'
+template: 'GuideTemplate'
+description: 'With our Events API you can ingest your data as the first step towards your quickstart contribution.'
+tags:
+ - quickstart
+---
+
+
+
+This guide will walk you through how to instrument your application to send event data into the New Relic's [Event API](https://docs.newrelic.com/docs/data-apis/ingest-apis/introduction-event-api/). The Event API allow you to send events to New Relic without a need for an agent. First, let's cover what events are. An event is a record of something happening somewhere. What triggers the event and what data is captured is up to you to customize, which we'll discuss next.
+
+
+
+## Capture Events in your Library
+
+At New Relic, we report events to data objects also called events. These events have multiple attributes (key-value pairs). We name each event record in our system with the event-type key.
+```json
+[{"event-type": "transaction"}]
+```
+The event-type key is how you will query the event data from NRQL. using the above example, this is how we would query for the data in NRQL:
+
+```sql
+From transaction select *
+```
+The rest in the event can be any custom key-value data, based on your library. When preparing the payload, consider the use case that makes the most sense for your users, and build the events accordingly. Here are some more resources about event data if you need more information.
+- [Events at New Relic](https://docs.newrelic.com/docs/data-apis/understand-data/new-relic-data-types/#events-new-relic)
+- [Formatting JSON](https://docs.newrelic.com/docs/data-apis/ingest-apis/introduction-event-api#instrument)
+
+## Send your events to New Relic
+There are a few ways we will discuss in order to send your event data into New Relic. We have our [telemetry SDK's](https://docs.newrelic.com/docs/data-apis/ingest-apis/telemetry-sdks-report-custom-telemetry-data), which are development kits instrumented to help you easily set up a POST request via several very common languages (C, Java, Python, .NET, etc.). We also have a basic curl command, which can be used on a windows or linux system to make a POST request to New Relic. We also have a prometheus option, if you use prometheus and have difficulty with the first two options.
+
+### New Relic License Key
+
+You will need to set up an environment variable for your users to input their [New Relic License key](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#ingest-license-key), or give an option for them to add it to the request header. The examples below will assume this variable is configured as `NEW_RELIC_INSERT_KEY`.
+
+### Send events via a curl/PowerShell command
+
+First, let's cover how you can send agentless data to New Relic, with just a simple command. These commands can be used in Linux or Windows environments. Here are some example requests for both
+
+* Linux/Bash
+
+```bash
+gzip -c example_events.json | curl -X POST -H "Content-Type: application/json" -H "Api-Key: NEW_RELIC_INSERT_KEY" -H "Content-Encoding: gzip" https://insights-collector.newrelic.com/v1/accounts/events --data-binary @-
+```
+* Windows/PowerShell
+```bash
+
+# Replace with your custom event for the body
+$body = $example_events
+
+$headers = @{}
+$headers.Add("Api-Key", "$NEW_RELIC_INSERT_KEY")
+$headers.Add("Content-Encoding", "gzip")
+
+
+$encoding = [System.Text.Encoding]::UTF8
+$enc_data = $encoding.GetBytes($body)
+
+$output = [System.IO.MemoryStream]::new()
+$gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
+
+$gzipStream.Write($enc_data, 0, $enc_data.Length)
+$gzipStream.Close()
+$gzipBody = $output.ToArray()
+
+Invoke-WebRequest -Headers $headers -Method Post -Body $gzipBody "https://insights-collector.newrelic.com/v1/accounts/events"
+```
+
+
+
+### Using our SDK's
+
+New Relic has a set of open source API client libraries that send data to New Relic. These operate by using our API's for data ingest, and in this case our event API. We have two SDK's that work with events, and those are Python and Java. Here we will walk through how to install each, and give a code example using both SDK's.
+
+For Python, you'll need to install the `newrelic-telemetry-sdk` package. you can do this by using pip:
+
+```bash
+$ pip install newrelic-telemetry-sdk
+```
+For Java, you will need to set up several dependencies:
+```java
+//Maven Dependencies
+
+ com.newrelic.telemetry
+ telemetry-core
+ 0.13.1
+
+
+ com.newrelic.telemetry
+ telemetry-http-okhttp
+ 0.13.1
+
+
+ //Gradle Dependencies
+ implementation("com.newrelic.telemetry:telemetry-core:0.13.1")
+ implementation("com.newrelic.telemetry:telemetry-http-okhttp:0.13.1")
+```
+
+Once our SDK is installed and ready, you can use the library to easily set up the api call to New Relic.
+
+* **Python**
+```Python
+import os
+import time
+from newrelic_telemetry_sdk import Event, EventClient
+
+# Record that a rate limit has been applied to an endpoint for an account
+event = Event(
+ "RateLimit", {"path": "/v1/endpoint", "accountId": 1000, "rejectRatio": 0.1}
+)
+
+event_client = EventClient(os.environ["NEW_RELIC_INSERT_KEY"])
+response = event_client.send(event)
+response.raise_for_status()
+print("Event sent successfully!")
+
+```
+* **Java**
+```java
+//Imports
+import static java.util.Collections.singleton;
+
+import com.newrelic.telemetry.Attributes;
+import com.newrelic.telemetry.OkHttpPoster;
+import com.newrelic.telemetry.TelemetryClient;
+import com.newrelic.telemetry.events.Event;
+import com.newrelic.telemetry.events.EventBatch;
+import java.net.InetAddress;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.UUID;
+
+public class TelemetryClientExample {
+
+ public static void main(String[] args) throws Exception {
+ String insightsInsertKey = args[0];
+
+ // create a TelemetryClient with an http connect timeout of 10 seconds.
+ TelemetryClient telemetryClient =
+ TelemetryClient.create(
+ () -> new OkHttpPoster(Duration.of(10, ChronoUnit.SECONDS)), insightsInsertKey);
+ Attributes commonAttributes =
+ new Attributes()
+ .put("exampleName", "TelemetryClientExample")
+ .put("service.name", "TelemetryClientExampleService")
+ .put("host.hostname", InetAddress.getLocalHost().getHostName())
+ .put("environment", "staging");
+
+
+ Span span = sendSampleEvent(telemetryClient, commonAttributes);
+
+ // make sure to shutdown the client, else the background Executor will stop the program from
+ // exiting.
+ telemetryClient.shutdown();
+ }
+
+ private static void sendSampleEvent(
+ TelemetryClient telemetryClient, Attributes commonAttributes) {
+ Event event = new Event("TestEvent", new Attributes().put("testKey", "testValue"));
+ telemetryClient.sendBatch(new EventBatch(singleton(event), commonAttributes));
+ }
+
+```
+### Alternative Options
+
+Other options available include using prometheus data, and installing a flex agent. We won't cover those in this guide, but here are some links to review these options.
+
+* [Prometheus Data](https://docs.newrelic.com/docs/infrastructure/prometheus-integrations/get-started/send-prometheus-metric-data-new-relic) - Prometheus data can be used by New Relic in two ways, [remote write](https://docs.newrelic.com/docs/infrastructure/prometheus-integrations/install-configure-remote-write/set-your-prometheus-remote-write-integration) and [OpenMetrics](https://docs.newrelic.com/docs/infrastructure/prometheus-integrations/install-configure-openmetrics/install-update-or-uninstall-your-prometheus-openmetrics-integration). At a very high level, remote write should be used if you manage your own prometheus servers, and OpenMetrics should be used if you do not.
+* [Flex Agent](https://github.com/newrelic/nri-flex/blob/master/docs/basic-tutorial.md#flex-step-by-step-tutorial) - Our serverless flex agent is a possibility if the other options do not work for you, but might be a more complex integration to get started.
\ No newline at end of file