Skip to content
lordmilko edited this page Sep 11, 2021 · 15 revisions

This article describes a feature that is currently under development. No guarantee is provided as to the safety, accuracy or completeness of the information contained within this article or its sub-articles.

Contents

PRTG Network Monitor internally stores its data as a tree. At the top of the tree are the various System nodes, below which are the various user-level nodes you are likely accustomed to from using the PRTG UI (sensors, probes, maps, schedules, etc).

System (ID: -1000)
├──Root (ID: 0)
│   └───Local Probe (ID: 1)
├──Users (ID: -1) 
│   └───PRTG System Administrator (ID: 100)
...

PrtgAPI provides an object model for manipulating the descendants of the Root node (ID: 0), consisting of the probes, groups, devices, sensors and notification triggers users usually interface with. The PrtgAPI Tree object model is heavily inspired by Roslyn, with additional inspiration taken from C# Expression Trees. If you have used either of these frameworks, the usage PrtgAPI.Tree should immediately be familiar to you.


While PrtgAPI's trees are not particularly complicated, due to their versatility it can seem like there's a lot of information in this section to get through; the most important details for most users will likely be found under Infrastructure As Code and Tree Migrations - everything else is just here to round out your understanding of things so you can take advantage of this API area as much as possible.


Object Model

PrtgAPI Trees are modeled via immutable, read-only nodes. Each node contains a Parent and a collection of Children. The PrtgNode class serves as the base of all node types that model PRTG Objects. The following tables describe the most common types of nodes you will interface with using PrtgAPI.

Base Nodes

The base nodes represent the core node types that are available within PrtgAPI. TreeNode serves as a non-generic, untyped implementation of a node. PrtgNode and CompareNode override many of the members in TreeNode to provide strongly typed interfaces specific for their purposes.

Type Description
TreeNode Base class for all node types (PrtgNode, CompareNode, etc)
PrtgNode Base class for all nodes used to model the PRTG Object Tree
CompareNode Represents a comparison of two PrtgNode objects

Common Nodes

The common nodes represent the core nodes used to model the PRTG Object Tree. Each node encapsulates an IPrtgObject or ISubObject returned from a PrtgClient.

Type Description
ChannelNode Encapsulates a Channel in the PRTG Object Tree
SensorNode Encapsulates a Sensor in the PRTG Object Tree
DeviceNode Encapsulates a Device in the PRTG Object Tree
GroupNode Encapsulates a Group in the PRTG Object Tree
ProbeNode Encapsulates a Probe in the PRTG Object Tree
TriggerNode Encapsulates a NotificationTrigger in the PRTG Object Tree
PropertyNode Encapsulates the property/setting of a node

Utility Nodes

Utility nodes help simplify working with the PRTG Object Tree, in particular scenarios involving multiple children that would otherwise create a mess.

PrtgNode

Type Description
PrtgNodeCollection Represents a collection of nodes (e.g. all Triggers or Properties of an object)
PrtgNodeGrouping Represents a grouping of nodes based on a common trait (e.g. all children of a node that contained the name "Ping")

CompareNode

Type Description
CompareNodeRoot Represents a comparison of trees that completely diverged at their first (root) nodes
CompareNodeGrouping Represents a grouping of nodes based on a common trait (e.g. all children of a node that contained the name "Ping")

Working with Trees

PrtgNode trees can be created in a number of ways. The simplest way to create a tree is via the PrtgClient.GetTree method

//Model the probe with ID 1
var tree = client.GetTree(1);

Trees can also be created from scratch (for applying changes to your PRTG Server) from an existing IObject via the static factory methods of the PrtgNode class

//Create a new tree from some probes, devices and groups that were previously
//retreived from PRTG
var tree = PrtgNode.Probe(probe1,
    PrtgNode.Device(device1,
        PrtgNode.Sensor(sensor1),
        PrtgNode.Sensor(sensor2)
    )
);

If you don't yet have the objects you wish to encapsulate, you can have PrtgAPI retrieve and wrap them for you via the PrtgNodeFactory class

//Create a tree containing the probe with ID 1, device with ID 1001 and sensors
//with IDs 2001 and 2002
var client = new PrtgClient("prtg.example.com", "username", "password");
var factory = new PrtgNodeFactory(client);

var tree = factory.Probe(1,
    factory.Device(1001,
        factory.Sensor(2001),
        factory.Sensor(2002)
    )
);

PrtgAPI provides several mechanisms to access the children of a node. Children can be accessed via the Children member, dynamic or an indexer.

//Get the first child of a tree
var child = deviceNode.Children[0];
//Get the "Ping" child of the device with ID 1001
dynamic deviceNode = client.GetTree(1001);
var ping = deviceNode.Ping;
var ping = deviceNode["Ping"];

When indexing into nodes, by default PrtgAPI will perform a case-sensitive lookup for the specified value. If you wish to ignore case, the ignoreCase parameter can be specified

var ping = deviceNode["ping", true];

If no matches are found when indexing into a value, null will be returned. If you are trying to index several levels deep without running into a NullReferenceException you can utilize null-conditional indexers.

var ping = probeNode["dc-1"]?["ping", true];
Clone this wiki locally