Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grafana 1.7.1 and Elasticsearch 7.9.0 Models and Job button not working #24

Open
fadjar340 opened this issue Oct 20, 2020 · 9 comments
Open

Comments

@fadjar340
Copy link
Collaborator

fadjar340 commented Oct 20, 2020

Dear @vsergeyev ,

I just run grafana-loudml-app in grafana 1.7.1 and using Elasticsearch 7.9.0.
The loudml server is on another server using same subnet, the installation of the grafana-loudml-app is very easy but I have something weird that the button on Add Model and Schedule Job not working.
image

I can create the temp-model using curl from grafana server to loudml server and it succeded, so the temp-model created, then I tried to edit the model but no luck.
Is there any specific requirement to make it work?

I use grafana-loudml-app v 1.7.1, BTW

Regards,
Fadjar340

@fadjar340 fadjar340 changed the title Grafana 1.7.1 and Elasticsearch 7.9.0 Models and Job nutton not working Grafana 1.7.1 and Elasticsearch 7.9.0 Models and Job button not working Oct 20, 2020
@fadjar340
Copy link
Collaborator Author

Also I tried using git clone,
when I ran yarn dev --watch, I got this:
image

And this condition likely hung but the process still running untuk I'm posting this.

Please give some clues to solve this problem...

Regards,
Fadjar340

@fadjar340
Copy link
Collaborator Author

Now I know the problems:
I found some problem when using git clone and build from source:

  1. for problem above with the @babel/preset-env, I solved it with
yarn add @babel/preset-env --dev

Then the issue was fixed
2. There some code that need to rectified,
In /src/panel/GraphPanel.tsx

// @ts-nocheck
import React from 'react';
import { GraphWithLegend, Chart } from '@grafana/ui';
import { GraphWithLegend2 } from './GraphWithLegend2';
import { PanelProps } from '@grafana/data';
import { Options } from './types';
import { GraphPanelController, CreateBaselineButton, MLModelController } from './GraphPanelController';
import { LegendDisplayMode } from '@grafana/ui/src/components/Legend/Legend';

interface GraphPanelProps extends PanelProps<Options> {}

It should be like below:

// @ts-nocheck
import React from 'react';
import { GraphWithLegend, Chart } from '@grafana/ui';
import { GraphWithLegend2 } from './GraphWithLegend2';
import { PanelProps } from '@grafana/data';
import { Options } from './types';
import { GraphPanelController, CreateBaselineButton, MLModelController } from './GraphPanelController';
import { LegendDisplayMode } from '@grafana/ui';

interface GraphPanelProps extends PanelProps<Options> {}
  1. In the /dist/datasource/module.js
   key: "addModel",
    value: function addModel() {
      this.model = Object.assign(Object.assign(Object.assign({}, types_1.DEFAULT_MODEL), {
        features: [Object.assign({}, types_1.DEFAULT_FEATURE)]
      }));
      app_events_1["default"].emit('show-modal', {
        src: '/public/plugins/loudml-grafana-app/datasource/partials/add_model.html',
        modalClass: 'confirm-modal',
        model: this
      });
    }
  }, {
    key: "editModel",
    value: function editModel(name) {
      var model = this.$scope.ctrl.modelsList.find(function (el) {
        return el.settings.name === name;
      });
      this.model = model.settings; // appEvents.emit(CoreEvents.showModal, {

      app_events_1["default"].emit('show-modal', {
        src: '/public/plugins/loudml-grafana-app/datasource/partials/add_model.html',
        modalClass: 'confirm-modal',
        model: this
      });
    }

Because you use static URL like

 src: '/public/plugins/loudml-grafana-app/datasource/partials/add_model.html',

Then when I use nginx as reverse proxy then the pagecan not shown because not found, and if I change the URL to the proper one, will look like below:
image

It will be the same as the Schedule job and other function that use static URL.

Perhaps you can fixed this in the source, and I'll try to rebuild...

Regards,
Fadjar340

@fadjar340
Copy link
Collaborator Author

Now I can show the page...
I change the code in src/datasource/config_ctrl.ts as below:

 key: "addModel",
    value: function addModel() {
      this.model = Object.assign(Object.assign(Object.assign({}, types_1.DEFAULT_MODEL), {
        features: [Object.assign({}, types_1.DEFAULT_FEATURE)]
      }));
      app_events_1["default"].emit('show-modal', {
        src: 'public/plugins/loudml-grafana-app/datasource/partials/add_model.html',
        modalClass: 'confirm-modal',
        model: this
      });
    }
  }, {
    key: "editModel",
    value: function editModel(name) {
      var model = this.$scope.ctrl.modelsList.find(function (el) {
        return el.settings.name === name;
      });
      this.model = model.settings; // appEvents.emit(CoreEvents.showModal, {

      app_events_1["default"].emit('show-modal', {
        src: 'public/plugins/loudml-grafana-app/datasource/partials/add_model.html',
        modalClass: 'confirm-modal',
        model: this
      });
    }

I remove in 4 lines and run yarn dev again.
Then viola...
The page shown now...
image

@fadjar340
Copy link
Collaborator Author

Next problem...
Maybe you forgot the output bucket in here:
image

Because in the dev console, I saw that output bucket parameter is undefined.
image

Or there are config about the output bucket that could be set to false?

@fadjar340
Copy link
Collaborator Author

I can train the model from loudml machine using loudml command...
then the datasource like below:
image

@fadjar340
Copy link
Collaborator Author

Still trying to make this work..

After I follow your youtube, I found that if elasticsearch as datasource, there is a bug about the model name, as follow
image

The apps read the index pattern that have * (asterisk) in the index pattern, then it creates the model name using * (asterisk) and then loudml rejected the naming of the model.
Perhaps you need to sanitize the special character from the index pattern in elasticsearch data source. Just use the value from the bucket, instead of the query result from elasticsearch datasource.
At this point, I can't go further to the code...

Regards,
Fadjar340

@fadjar340
Copy link
Collaborator Author

Ohh my...

After searching and googling also understand the code...
I have succeded to save the model..

In src/panel/GrapPanelController.tst at line 436 i change the replace command to replace all unnecesary character

  this.getDatasource(source.datasource)
      .then(result => {
        this.datasource = result;
        // TODO: find a way to pass all this.datasource connection params to Loud ML server
        // This will allow to auto create bucket to store ML Model training results

        // this.ds.loudml.createAndGetBucket(
        //   this.datasource.database,
        //   source.policy,
        //   source.measurement,
        //   this.datasource
        // ).then(result => {
        //     const bucket = result;
        const bucket = this.props.panelOptions.datasourceOptions.input_bucket;
        const output_bucket = this.props.panelOptions.datasourceOptions.output_bucket;
        const measurement = extract_model_measurement(source);
        const fill = extract_model_fill(source);
        const match_all = extract_model_tags_map(source);
        const name = [
          extract_model_database(this.datasource),
          measurement,
          extract_model_select(source, fields[0]), // will use 1st metric to name model - fields[0]
          extract_model_tags(source),
          extract_model_time_format(source),
        ]
          .join('_')
          // .replace(/\./g, '_');
          .replace(/[.*+?^${}()|[\]\\]/g, '_');

        // Group By Value – [{params: ["5m"], type: "time"}, {params: ["linear"], type: "fill"}]
        // Let parse a "5m" time from it
        const time = extract_model_time(source);
        const model = {
          ...DEFAULT_MODEL,
          max_evals: 10,
          name: name,
          interval: this.normalizeInterval(time),
          span: this.normalizeSpan(time),
          default_bucket: bucket, //bucket.name - if we will use createAndGetBucket()
          bucket_interval: time,
          features: fields.map(field => ({
            name: extract_model_select(source, field),
            measurement: measurement,
            field: extract_model_feature(source, field),
            metric: extract_model_func(source, field), // aggregator, avg/mean
            io: 'io',
            default: fill,
            match_all: match_all,
          })),
	};

Below the result
image

Then the model saved and start to training....

@vsergeyev
Copy link
Owner

Dear @fadjar340

You have done a lot of fixes and your comments and details are of a big value!

Output bucket field is in LoudML Panel. Please try if it set properly.
(in datasource it is old field for output bucket, it not used)

Your patches are great, please try to create a git pull request.
From my side I will be happy to include you into repository authors list.

Stay cool!

V.

@fadjar340
Copy link
Collaborator Author

Please send me the password to commit my changes...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants