Grafana Live measurements

I’m trying to set up a live measurement using telegrafs opc plugin. I’ve successfully configured the websocket output pluggin, but grafana only seems to be picking up the last measurement in the OPC node. Example:

the opc node in the Telegraf input config is as follows:

  [[inputs.opcua.group]]
    name = "Conveyor01"
    namespace = "3"
    identifier_type = "s"
    nodes = [
       {name = "Totalizer",identifier = "[xxxxxxxx]Conveyor01.Totalizer"},
       {name = "Faulted",identifier = "[xxxxxxxx]Conveyor01.Faulted"},
       {name = "FaultedTime",identifier = "[xxxxxxxx]Conveyor01.FaultedTime"},
       {name = "IdleTime",identifier = "[xxxxxxxx]Conveyor01.IdleTime"},
       {name = "Running",identifier = "[xxxxxxxx]Conveyor01.Running"},
       {name = "RunningTime",identifier = "[xxxxxxxx]Conveyor01.RunningTime"},
       {name = "Tons",identifier = "[xxxxxxxx]Conveyor01.Tons"},
       {name = "Idle",identifier = "[xxxxxxxx]Conveyor01.Idle"}
]

the output config is as follows:

[[outputs.websocket]]
  url = "ws://xxxxxxxx/api/live/push/opc"
  data_format = "influx"
  namepass = ["Conveyor*"]
 [outputs.websocket.headers]
    Authorization = "Bearer <my token>"

The telegraf logs show no issue and when I set up a table in a grafana dashboard linked to this channel the only field returning a value is the last one,totalizer. The rest are returning NaN’s. I’ve tested this by removing fields from the input node and the measure will start recording, it seems to always return the last measure in the node. Any advice would be appreciated.

Hi @bharvey, welcome to the community,

Well, I am not expert with such plugin but will like to give a try and maybe some other community members can help further.

As a starting point, did you found any errors in the Grafana logs under /var/log/grafana/grafana.log

Also, the datasource i.e. telegraf you configured, does it have the right permissions to view the statistics output of the plugin.

Here is the from the log file from when I was playing around with this. I did notice something on friday. It seems that it can handle measurements with multiple fields in a single line, but not measurements with multiple lines for each field. the opc connection instead writes each node to it’s own line. Example below:

> Conveyor02,host=xxxxxx FaultedTime=227i 1657923448000000000
> Conveyor02,host=xxxxxx FaultedTime=227i 1657923448000000000
> Conveyor02,host=xxxxxx IdleTime=1739i 1657923448000000000
> Conveyor02,host=xxxxxx IdleTime=1739i 1657923448000000000
> Conveyor02,host=xxxxxx Running=false 1657923448000000000
> Conveyor02,host=xxxxxx Running=false 1657923448000000000

But this format is fine:

 Server_Room,host=xxxxxxxx,name=Temp_PLC,slave_id=1,type=holding_register Temp1=28.9615478515625,Temp2=27.82330322265625,Temp3=22.52264404296875,Temp4=23.75 1658160151000000000
logger=context t=2022-07-15T13:37:22.49-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/OPC_Grouped status=401 remote_addr=[::1] time_ms=0 size=40 referer=
logger=context t=2022-07-15T13:37:59.19-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=1 size=0 referer=
logger=context t=2022-07-15T13:43:04.38-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/OPC_Grouped/OPC status=404 remote_addr=[::1] time_ms=69 size=24 referer=
logger=context t=2022-07-15T13:43:19.46-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/OPC_Grouped/OPC status=404 remote_addr=[::1] time_ms=67 size=24 referer=
logger=context t=2022-07-15T13:47:35.34-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=31 size=0 referer=
logger=context t=2022-07-15T13:48:02.7-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id status=0 remote_addr=[::1] time_ms=175 size=0 referer=
logger=live t=2022-07-15T13:48:08.22-0700 lvl=info msg="Initialized channel handler" channel=plugin/testdata/random-flakey-stream address=plugin/testdata/random-flakey-stream
logger=live t=2022-07-15T13:48:14.29-0700 lvl=info msg="Initialized channel handler" channel=plugin/testdata/random-labeled-stream address=plugin/testdata/random-labeled-stream
logger=context t=2022-07-15T13:49:02.58-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id status=0 remote_addr=[::1] time_ms=73 size=0 referer=
logger=context t=2022-07-15T13:50:11.85-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=115 size=24 referer=
logger=context t=2022-07-15T13:50:21.76-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=37 size=24 referer=
logger=context t=2022-07-15T13:50:31.83-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=81 size=24 referer=
logger=live t=2022-07-15T13:50:37.93-0700 lvl=info msg="Initialized channel handler" channel=stream/custom_stream_id/Conveyor01 address=stream/custom_stream_id/Conveyor01
logger=context t=2022-07-15T13:50:41.8-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=70 size=24 referer=
logger=context t=2022-07-15T13:50:51.79-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=60 size=24 referer=
logger=context t=2022-07-15T13:51:01.82-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=74 size=24 referer=
logger=context t=2022-07-15T13:51:11.85-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=98 size=24 referer=
logger=context t=2022-07-15T13:51:21.82-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=72 size=24 referer=
logger=context t=2022-07-15T13:51:31.63-0700 lvl=info msg="Request Completed" method=POST path=/api/live/push/custom_stream_id/opc status=404 remote_addr=[::1] time_ms=51 size=24 referer=
logger=context t=2022-07-15T13:52:24.6-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=4 size=0 referer=
logger=context t=2022-07-15T13:54:34.17-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=3 size=0 referer=
logger=licensing t=2022-07-15T13:54:52.9-0700 lvl=info msg="Validated license token" appURL=http://localhost:3000/ source=disk status=NotFound
logger=licensing.renewal t=2022-07-15T13:54:52.9-0700 lvl=warn msg="failed to load or validate token" err="license token file not found: C:\\Program Files\\GrafanaLabs\\grafana\\data\\license.jwt"
logger=live t=2022-07-15T13:56:27.52-0700 lvl=info msg="Initialized channel handler" channel=stream/opc/Conveyor01 address=stream/opc/Conveyor01
logger=live t=2022-07-15T13:57:19.31-0700 lvl=info msg="Initialized channel handler" channel=stream/opc/Conveyor02 address=stream/opc/Conveyor02
logger=context t=2022-07-15T14:02:17.16-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/opc status=0 remote_addr=[::1] time_ms=491015 size=0 referer=
logger=context t=2022-07-15T14:23:37.77-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=5 size=0 referer=
logger=context t=2022-07-15T14:28:03.72-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/opc status=0 remote_addr=[::1] time_ms=307160 size=0 referer=
logger=context t=2022-07-15T14:28:37.08-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=1 size=0 referer=
logger=context t=2022-07-15T14:31:16-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/opc status=0 remote_addr=[::1] time_ms=2650 size=0 referer=
logger=context t=2022-07-15T14:31:53.79-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=14 size=0 referer=
logger=context t=2022-07-15T14:34:18.72-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/opc status=0 remote_addr=[::1] time_ms=163366 size=0 referer=
logger=live t=2022-07-15T14:44:04.66-0700 lvl=info msg="Initialized channel handler" channel=stream/custom_stream_id/Server_Room address=stream/custom_stream_id/Server_Room
logger=context t=2022-07-15T14:49:09.04-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=70 size=0 referer=
logger=context t=2022-07-15T14:50:10.2-0700 lvl=info msg="Request Completed" method=GET path=/api/live/push/opc status=0 remote_addr=[::1] time_ms=68638 size=0 referer=
logger=licensing t=2022-07-15T14:54:53.1-0700 lvl=info msg="Validated license token" appURL=http://localhost:3000/ source=disk status=NotFound
logger=licensing.renewal t=2022-07-15T14:54:53.1-0700 lvl=warn msg="failed to load or validate token" err="license token file not found: C:\\Program Files\\GrafanaLabs\\grafana\\data\\license.jwt"
logger=context t=2022-07-15T15:53:57.56-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=2 size=0 referer=
logger=live t=2022-07-15T15:54:10.08-0700 lvl=info msg="Initialized channel handler" channel=stream/opc/CPU address=stream/opc/CPU
logger=licensing t=2022-07-15T15:54:53.3-0700 lvl=info msg="Validated license token" appURL=http://localhost:3000/ source=disk status=NotFound
logger=licensing.renewal t=2022-07-15T15:54:53.3-0700 lvl=warn msg="failed to load or validate token" err="license token file not found: C:\\Program Files\\GrafanaLabs\\grafana\\data\\license.jwt"
logger=live t=2022-07-15T15:59:30.73-0700 lvl=info msg="Initialized channel handler" channel=grafana/dashboard/uid/ttaLQGgVk address=grafana/dashboard/uid/ttaLQGgVk
logger=context t=2022-07-15T16:01:43.44-0700 lvl=info msg="Request Completed" method=GET path=/login status=302 remote_addr=[::1] time_ms=7 size=24 referer=
logger=context t=2022-07-15T16:01:45.53-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=3 size=0 referer=
logger=context t=2022-07-15T16:04:05.32-0700 lvl=info msg="Request Completed" method=GET path=/api/live/ws status=0 remote_addr=[::1] time_ms=24 size=0 referer=

Thanks for the help.

Hi @bharvey,

Not sure if you were able to figure it out.

Incase not then please review the submission template and include more details:

  • What Grafana version and what operating system are you using?
  • What is your datasource?
  • What are you trying to achieve?
  • How are you trying to achieve it?
  • What happened?
  • What did you expect to happen?
  • Can you copy/paste the configuration(s) that you are having problems with?
  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.
  • Did you follow any online instructions? If so, what is the URL?

I have not figured this out yet.

  • What Grafana version and what operating system are you using?
    grafana 8.4.4
  • datasource:
    OPC server sending simulated pump data
  • what are you trying to achieve?
    We want to visualize live OPC data in grafana as a proof of concept
  • How are you trying to achieve?
    I’m using telegraf and websocket to stream data to grafana as per the telegraf lab i followed.
  • What did I expect to happen?
    to be able to see the data from all my nodes, not just the last node in the group.

here is the structure of the opc group from the telegraf config:

[[inputs.opcua.group]]
    name = "Pump01"
    namespace = "2"
    identifier_type = "i"
    nodes = [
       {name = "Motor Casing Vibration",identifier = "3",tags = [["part","motor"]]},
       {name = "Motor Frequency A",identifier = "4",tags = [["part","motor"]]},
       {name = "Motor Frequency B",identifier = "5",tags = [["part","motor"]]},
       {name = "Motor Frequency C",identifier = "6",tags = [["part","motor"]]},
       {name = "Motor Speed",identifier = "7",tags = [["part","motor"]]},
       {name = "Motor Current",identifier = "8",tags = [["part","motor"]]},

it’s not an issue with telegraf as the data is currently being correcltly stored in influxdb

    • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.?
      no errors in the ui, It is returning empty columns except for the last column returned
  • Did you follow any online instructions?
    yes, I followed the grafana lab on streaming live data using telegraf.

Thanks,

So I guess you are using InfluxDB ver. 2.x.x?

Also, if I understand it correctly, the same query seems to be showing correctly for all the nodes?

Also, as you mentioned that that data is coming only for the last node. Is the telegraf agent installed on all other nodes ?

no, I think we are getting confused in terminology here. we have a VM set up with telegraf, influx and grafana. I’m writing data to influx and would also like to stream it to grafana, I’m using the term node to refer to the node in the opc data stream in the tree ( see below). This configuration writes to influx correctly, so it’s not an issue with the config. What’s happening is, when I configure the telegraf output to send metrics to grafana through a websocket the only data to show up is the last data node in the config file. So in the example below the only data to stream is Motor current. The other tags would show up in the granafa GUI but arent streaming any data

Telegraf input config:

  [[inputs.opcua.group]]
    name = "Pump01"
    namespace = "2"
    identifier_type = "i"
    nodes = [
       {name = "Motor Casing Vibration",identifier = "3",tags = [["part","motor"]]},
       {name = "Motor Frequency A",identifier = "4",tags = [["part","motor"]]},
       {name = "Motor Frequency B",identifier = "5",tags = [["part","motor"]]},
       {name = "Motor Frequency C",identifier = "6",tags = [["part","motor"]]},
       {name = "Motor Speed",identifier = "7",tags = [["part","motor"]]},
       {name = "Motor Current",identifier = "8",tags = [["part","motor"]]}
]

telegraf out put config:

[[outputs.websocket]]
  url = "ws://xxxxxxxxxxx/api/live/push/opc"
  alias = "websocket_output"
  data_format = "influx"
  flush_interval = "2s"

  [outputs.websocket.headers]
    Authorization = "Bearer <SECRET KEY>

did you mean send metrics to influx?

No, telegraf has two output plugins one writing to an influx bucket and If you look at the telegraf config above you will see it’s also writing to a grafana websocket. Here is a link to grafana labs explaining the concept.

1 Like