Search code examples
logginggrafanagrafana-plugin

Grafana logs plugin doesn't show logs panel


I'm trying to create a Grafana plugin that supports the logs panel. I'm following the directions from their website.

Unfortunately it doesn't seem to work. I've added "logs": true to plugin.json and am returning a field of type time called "time", a field of type string called "level", and a field of type string called "content", following along with their example. I'm returning essentially the same thing as the example shows.

export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
  constructor(instanceSettings: DataSourceInstanceSettings<MyDataSourceOptions>) {
    super(instanceSettings);
  }

  async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
    // Return a constant for each query.
    const data = options.targets.map(target => {
      const query = defaults(target, defaultQuery);
      const frame = new MutableDataFrame({
        refId: query.refId,
        fields: [
          { name: 'time', type: FieldType.time },
          { name: 'level', type: FieldType.string },
          { name: 'content', type: FieldType.string },
        ],
      });
      frame.add({ time: 1615422190000, level: 'warn', content: 'hi' });
      frame.add({ time: 1615422191000, level: 'info', content: 'bye' });
      return frame;
    });

    return { data };
  }

  async testDatasource() {
    // Implement a health check for your data source.
    return {
      status: 'success',
      message: 'Success',
    };
  }
}

Yet in Grafana (running the latest stable version, 7.4.3) when I load my plugin I am unable to get the log panel in Explore and in the Dashboard query interface if I choose the log panel it displays the data but incorrectly:

broken grafana logs panel

Is there something else I need to do to make the log panel work? The instructions claim I just need to return a field of type time and a field of type string with "logs": true set in plugin.json, but that's not working.

The only real hint I can find so far is this other SO question about the MSSQL plugin, which suggests that maybe something about this function in that plugin would show how the data needs to be formatted, but it's not clear to me reading the source what that might be and how it's different from what I'm doing now.

ETA: Looks like this question asked something similar but the answer doesn't make it clear what the issue was since it seems in their case they were returning a result of the wrong type altogether.


Solution

  • I figured out part of the answer. It's necessary to include the following in the MutableDataFrame:

    meta: {
      preferredVisualisationType: 'logs',
    },
    

    to get it to "activate" in Explore. However I don't think this is the whole answer because the view is still broken in the Dashboard panel as described in the question and in the Explore view it kinda works but doesn't pull out any fields by default to display; they have to be manually turned on by opening the log line and clicking the eye icon to make a field visible.

    ETA: Okay, the rest of the answer on why the view appears broken is because of how the logs visualization decides what data to show. It's in the docs but not called out perhaps as clearly as it should be. It says:

    If a data frame has more than one text field, then Grafana assumes the first field in the data frame to be the actual log line. Any subsequent text fields are treated as detected fields.

    So the format of the data needs to be a certain way, and in particular the first string field needs to be the "message" to display. It looks the way it does above because I put level before content. Reversing those makes it work as expected.