MELT Data


Sending MELT signal data


In order to fully test the telemetry ingestion for entities, you will need to generate telemetry data representing the different MELT signals associated with each entity.

The fsoc melt model command allows you to quickly generate a telemetry data model file that will provide you most of what you need to test metrics, logs, and events telemetry ingestion for all entities defined in your solution’s domain model.

At the time this content was published, fsoc supported the following aspects of mocking up and pushing MELT data:

  • Metrics
    • Sum
    • Gauge
    • Distribution (hopefully coming soon)
  • Events
  • Logs
  • Traces (supported but need a good example)
    • If you’re looking for a way to generate and push mock traces and spans, another generator for that can be found here
    • Test Telemetry Generator


Generate sample MELT data

The fsoc utility generates mock MELT data based on your solutions entity and metric definitions in their current state on your local file system. If you add new entities, entity attributes, or metrics, you will need to regenerate the mock MELT Yaml file which always has empty values for entity attributes, etc., in it or manually update your existing mock MELT Yaml file to account for your changes.

  Dev Tip When adding metrics to your enities with metricTypes, you should consider ordering them in the way that you want the fsoc melt model command to output them in the melt.yaml file it generates. This pays off the most when you have many metrics for a given entity that you may want formed into logical groupings (e.g. cpu, memory, disk, network, etc.) to make it easier for you to adjust the metric values that will be sent.


  Use the commands below to generate a mock MELT Yaml file.


Windows Example Commands:

cd C:\fsoc_projects\my_tenant\ugottaride

fsoc melt model

Unix-Mac Example Commands:

cd /fsoc_projects/my_tenant/ugottaride

fsoc melt model 

image

What did these fsoc commands do?

  • Created a new mock MELT data Yaml file under
    • /fsoc_projects/my_tenant/ugottaride
    • ugottaride-0.0.1-melt.yaml
  • Created 5 entries in the file, one for each of our defined entities along with an entry for each metric in context of the entity that is utilizing it.


Update sample MELT data

The new ugottaride-0.0.1-melt.yaml file created should have entries for all 5 entities (assuming you created all 5 entity definitions previously). However, we want to control the timing and order of the payloads sent so we can independently test our association declaration and association derivations that define the relationship between our entities.

We will be creating three more MELT YAML files and copy the entity entries into the new Yaml files as seen below:

  1. /fsoc_projects/my_tenant/ugottaride/001-melt.yaml
    • rider entity
    • ride entity
  2. /fsoc_projects/my_tenant/ugottaride/002-melt.yaml
    • driver entity
    • vehicle entity
  3. /fsoc_projects/my_tenant/ugottaride/003-melt.yaml
    • ride_assign entity


  Before we do that, let’s take a look at some important sections within the MELT Yaml file to understand their purpose and implications.

  1. Here we have the attributes section for an entity type, in this case the rider entity. In this example we have already populated the attribues with values.
  2. This section has definitions for the metric(s) we have added to our entity. Notice (lines 14 and 15) where we have manually added the min and max to the metric details which allow us to control the minimum and maximum values sent for the metric.
    • If you want a metric value to be constant each time it is sent, you can simply set the min and max to the same value here.
  3. The logs section (16 - 24) allows us to send mock logs for our entity and allows us to specify the severity level as well as the content or body of the log sent.
  4. For association declaration relationships, the parent entity (here the parent = rider), must declare it’s relationship to any child or children that are part of the parents association declaration(s). In our example here, we have the child defininition starting on line 31 with its attributes that include the rideid of the ride.
    • The rideid is both a required attribute of the ride entity but more importantly, it happens to be the single attribute that makles a ride entity instance unique.
    • This is why we are declaring the rideid attribute on line 27 in the relationships section, to establish the relationship between this rider and ride. Notice on line 28 that we are also declaring the type of entity that this attribute relates to (which must always be done after the last attribute for a specific child entity in the relationships section).
  5. We previously mentioned that the use of entity priorities requires that you send the telemetry.sdk.name attribute in your payload for each entity, and that the value of that attribute must match the value declared in the scopeFilter (line 11) within your enity priorities definition.
    • This is exactly what we see here and it is highly recommended that the value should be the namespace of your solution, to make it unique to your solution and your solutions entities.

image

  Dev Tip When using association declarations to relate your entities, you will always need to have the child or children of the parent referenced in the parents relationships section in the parent as seen above on lines 25 - 28.


In the image below, we are looking at portions of the 3 different MELT Yaml files that we will yet create, to help explain what is needed in the MELT Yaml files to support our entities with association derivation relationships.

When you send MELT data for a child involved in an association derivation (which assumes after the parent(s) have already been persisted), you must have knowledge of the attribute(s) value(s) of the parent(s) that make the parent entity instance(s) unique. This is required so the platform can determine what parent entity or entities the child is related to and can accurately establish the correct relationship(s).

For association derivations, we need to populate the “primary key” attributes (with their values) of the related parent(s) in the attributes of the child as seen in our example MELT payload definition for the ride_assign child entity.

Recall that two of the three “golden rules” when using association derivations are:

  • The child entity must have an additional attribute or attributes that match the primary key attribute(s) of the parent that is already persisted
  • The primary key attribute(s) of the parent must be sent as attributes in the child resource attributes. This creates the link between the child and the parent within the single payload.

When we created the entity definition for the ride_assign entity, we added primary key attributes of the three related parents (ride, driver, vehicle) to our ride_assign child entity. Now we must include those attributes with values in the payload for our child entity (ride_assign).

  1. Here we are including the ugottaride.ride_assign.rideid, matching the rideid of the ride entity.
  2. Here we are including the ugottaride.ride_assign.driverid, matching the driverid of the driver entity.
  3. Here we are including the ugottaride.ride_assign.vin, matching the vin of the vehicle entity.
  4. Though it might seem a bit redundant to re-declare the type of the entity (ride_assign) on line 10, it is required in this scenario where we are trying to establish the association derivation.

image


  Below are the full contents of the 3 different MELT Yaml files you need to create now so we can push them, one at a time, in the next step.


/fsoc_projects/my_tenant/ugottaride/001-melt.yaml

melt:
- typename: ugottaride:rider
  attributes:
    ugottaride.rider.display_name: "Mr. Bond"
    ugottaride.rider.first_name: "Frank"
    ugottaride.rider.last_name: "Bond"
    ugottaride.rider.riderid: "10000"
    telemetry.sdk.name: "ugottaride"
  metrics:
  - typename: ugottaride:miles_traveled
    contenttype: gauge
    unit: ""
    type: long
    min: "5"
    max: "20"     
  logs:
  - body: hello world-0 for an entity of type ugottaride:rider
    severity: INFO
    attributes:
      level: info
  - body: hello world-1 for an entity of type ugottaride:rider
    severity: INFO
    attributes:
      level: info
  relationships:
    - attributes:
        ugottaride.ride.rideid: "20000"
        ugottaride.type: "ride"
  spans: []

- typename: ugottaride:ride
  attributes:
    ugottaride.ride.ride_category: "luxo"
    ugottaride.ride.ride_status: "requested"
    ugottaride.ride.rideid: "20000"
    ugottaride.ride.travel_time_minutes: 1
    telemetry.sdk.name: "ugottaride"
  metrics:
  - typename: ugottaride:miles_per_hour
    contenttype: gauge
    unit: ""
    type: long
    min: "85"
    max: "162"     
  - typename: ugottaride:miles_traveled
    contenttype: gauge
    unit: ""
    type: long
    min: "5"
    max: "20"     
  logs:
  - body: hello world-0 for an entity of type ugottaride:ride
    severity: INFO
    attributes:
      level: info
  - body: hello world-1 for an entity of type ugottaride:ride
    severity: INFO
    attributes:
      level: info
  relationships: []
  spans: []


/fsoc_projects/my_tenant/ugottaride/002-melt.yaml

melt:
- typename: ugottaride:driver
  attributes:
    ugottaride.driver.display_name: "The Wolf"
    ugottaride.driver.driverid: "30000"
    ugottaride.driver.first_name: "Winston"
    ugottaride.driver.last_name: "Harvey"
    telemetry.sdk.name: "ugottaride"
  metrics:
  - typename: ugottaride:miles_per_hour
    contenttype: gauge
    unit: ""
    type: long
    min: "140"
    max: "147"         
  - typename: ugottaride:engine_rpm
    contenttype: gauge
    unit: '{rpm}'
    type: long
    min: "4000"
    max: "8000"      
  - typename: ugottaride:miles_traveled
    contenttype: gauge
    unit: ""
    type: long
    min: "5"
    max: "80"      
  logs:
  - body: hello world-0 for an entity of type ugottaride:driver
    severity: INFO
    attributes:
      level: info
  - body: hello world-1 for an entity of type ugottaride:driver
    severity: INFO
    attributes:
      level: info
  relationships: []
  spans: []

- typename: ugottaride:vehicle
  attributes:
    ugottaride.vehicle.exterior_color: "Silver"
    ugottaride.vehicle.make_model: "Acura NSX"
    ugottaride.vehicle.plate_number: "3ABM581"
    ugottaride.vehicle.vin: "19UNC1B05NY000094"
    telemetry.sdk.name: "ugottaride"
  metrics:
  - typename: ugottaride:miles_per_hour
    contenttype: gauge
    unit: ""
    type: long
    min: "140"
    max: "147"     
  - typename: ugottaride:miles_traveled
    contenttype: gauge
    unit: ""
    type: long
    min: "5"
    max: "80"       
  - typename: ugottaride:engine_rpm
    contenttype: gauge
    unit: '{rpm}'
    type: long
    min: "4000"
    max: "8000"    
  - typename: ugottaride:engine_temperature
    contenttype: gauge
    unit: '{degrees f}'
    type: long
    min: "190"
    max: "225"    
  logs:
  - body: hello world-0 for an entity of type ugottaride:vehicle
    severity: INFO
    attributes:
      level: info
  - body: hello world-1 for an entity of type ugottaride:vehicle
    severity: INFO
    attributes:
      level: info
  relationships: []
  spans: []


/fsoc_projects/my_tenant/ugottaride/003-melt.yaml

melt:
- typename: ugottaride:ride_assign
  attributes:
    ugottaride.ride_assign.assignid: "50000"
    ugottaride.ride_assign.rideid: "20000"
    ugottaride.ride_assign.driverid: "30000"
    ugottaride.ride_assign.vin: "19UNC1B05NY000094"
    ugottaride.ride_assign.assign_status: "confirmed"
    telemetry.sdk.name: "ugottaride"
    ugottaride.type: "ride_assign"    
  metrics: []
  logs:
  - body: hello world-0 for an entity of type ugottaride:ride_assign
    severity: INFO
    attributes:
      level: info
  - body: hello world-1 for an entity of type ugottaride:ride_assign
    severity: INFO
    attributes:
      level: info


Push sample MELT data

Now it is finally time to push our mock MELT data to our solution! Make sure you use the name of your agent principal profile name with the –profile option seen below. Specifying your agent principal profile in the fsoc -v melt push –dump command tells fsoc to temporarily use the specified profile for this command only.

Windows Example Commands:

cd C:\fsoc_projects\my_tenant\ugottaride

fsoc -v melt push --dump 001-melt.yaml --profile my-ap-profile

wait 30 seconds

fsoc -v melt push --dump 002-melt.yaml --profile my-ap-profile

wait 30 seconds

fsoc -v melt push --dump 003-melt.yaml --profile my-ap-profile


Unix-Mac Example Commands:

cd /fsoc_projects/my_tenant/ugottaride

fsoc -v melt push --dump 001-melt.yaml --profile my-ap-profile

wait 30 seconds

fsoc -v melt push --dump 002-melt.yaml --profile my-ap-profile

wait 30 seconds

fsoc -v melt push --dump 003-melt.yaml --profile my-ap-profile


  Dev Tip Whenever you make a change to your enity model that would change the structure of your enities, associations, or metrics you should make sure you update your MELT Yaml before you push the MELT, otherwise, your MELT data will not match your model.


Validating entity and metric persistence

Now that we have pushed out mock MELT data, we will use UQL queries with fsoc to validate that our entities, as well as the relationships between them have been persisted / established.


Query your entities and metrics

Rider Entity Query:

Check to see if your rider entity was persisted along with the metric associated with it using fsoc to run the UQL query seen below.

UQL Query Format – (replace <solution_namespace> with your solution namespace)

fsoc uql "since now - 1h FETCH attributes('riderid'), attributes('display_name'), attributes('first_name'), attributes('last_name'), metrics('<solution_namespace>:miles_traveled') from entities('<solution_namespace>:rider')"

UQL Query example

fsoc uql "since now - 1h FETCH attributes('riderid'), attributes('display_name'), attributes('first_name'), attributes('last_name'), metrics('ugottaride:miles_traveled') from entities('ugottaride:rider')"

image


Rider Entity with Associated Ride Entity Query:

Check to see if your rider entity has the relationship persited with the ride entity using fsoc to run the UQL query seen below.

UQL Query Format – (replace <solution_namespace> with your solution namespace)

fsoc uql "since now - 1h FETCH type,count FROM entities(<solution_namespace>:rider).out.to()"

UQL Query example

fsoc uql "since now - 1h FETCH type,count FROM entities(ugottaride:rider).out.to()"

image


Ride Assign Entity with Parent Entities Query:

Check the persistence of the ride_assign entity along with its parent associations using fsoc to run the UQL query seen below.

UQL Query Format – (replace <solution_namespace> with your solution namespace)

fsoc uql "since now - 1h FETCH type,count,attributes('rideid'), attributes('driverid'), attributes('vin') from entities('<solution_namespace>:ride_assign').in.from()"

UQL Query example

fsoc uql "since now - 1h FETCH type,count,attributes('rideid'), attributes('driverid'), attributes('vin') from entities('ugottaride:ride_assign').in.from()"

image


Next Steps  

We’ll dive into creating the UI for our solution.

Click here to continue