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

[Maps] Enh/gis telemetry #29346

Merged
merged 22 commits into from
Feb 5, 2019
Merged

[Maps] Enh/gis telemetry #29346

merged 22 commits into from
Feb 5, 2019

Conversation

kindsun
Copy link
Contributor

@kindsun kindsun commented Jan 25, 2019

Resolves #26715. Adds telemetry for the following:

  • Total count of maps
  • Min, max, avg count of layers per map
  • Min, max, avg of layers by type
  • Min, max, avg of layers by EMS region
  • Min, max, avg of data sources per map

@elasticmachine
Copy link
Contributor

💔 Build Failed

@thomasneirynck thomasneirynck changed the title Enh/gis telemetry [Maps] Enh/gis telemetry Jan 28, 2019
@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@kindsun kindsun added enhancement New value added to drive a business result v7.0.0 v6.7.0 [Deprecated-Use Team:Presentation]Team:Geo Former Team Label for Geo Team. Now use Team:Presentation labels Jan 29, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-gis

@kindsun
Copy link
Contributor Author

kindsun commented Jan 29, 2019

@alexfrancoeur I'm in the process of writing tests for this PR now, would be good to verify this covers what you requested in #26715. I think the only thing we aren't getting are basemaps since basemap at this point is kind of an informal designation of a tilemap layer. Here's a sample of the saved JSON data currently:

"maps":{
   "maps_total_count":2,
   "attributes_per_map":{
      "data_sources_count":{
         "min":3,
         "max":4,
         "avg":3.5
      },
      "layers_count":{
         "min":3,
         "max":4,
         "avg":3.5
      },
      "layer_types_count":{
         "tile":{
            "min":1,
            "max":2,
            "avg":1.5
         },
         "vector":{
            "min":2,
            "max":2,
            "avg":2
         }
      },
      "ems_vector_layers_count":{
         "world_countries":{
            "min":1,
            "max":1,
            "avg":1
         },
         "canada_provinces":{
            "min":1,
            "max":1,
            "avg":1
         }
      }
   }
}

@alexfrancoeur
Copy link

alexfrancoeur commented Jan 29, 2019

😮 @aaronjcaldwell, this is perfect. The data and structure look good to me 👍

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neato, some minor comments

xpackMainPlugin.info
.feature(thisPlugin.id)
.registerLicenseCheckResultsGenerator(checkLicense);
const thisPlugin = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to reassign, this is used in same lexical scope

type: 'gis-map'
});

const savedMaps = _.get(gisMapsSavedObject, 'saved_objects')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to layerLists

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny, that's exactly what it was before but I changed it to savedMaps thinking that was more differentiating and clear here. I'll change it back though

// Count of EMS Vector layers used
const emsLayersCount = savedMaps.map(lList => _(lList)
.countBy(layer => {
const isEmsFile = _.get(layer, 'sourceDescriptor.type') === 'EMS_FILE';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract this constant EMS_FILE to constant (e.g. in `common/constants.js), so it can be referenced from single spot (right now, constant is defined here: https://github.com/thomasneirynck/kibana/blob/9520a812981bf58f37dfa40758af6e99d1af6a0f/x-pack/plugins/gis/public/shared/layers/sources/ems_file_source/ems_file_source.js#L16)

import { TASK_ID, scheduleTask, registerMapsTelemetryTask } from './telemetry_task';

export function initTelemetryCollection(server) {
const { taskManager } = server;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fluffy line. can just use server.taskManager like you do elsewhere in the file.

}

export function registerMapsUsageCollector(server) {
const { usage } = server;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

@elasticmachine
Copy link
Contributor

💔 Build Failed

@kindsun kindsun requested a review from tsullivan February 1, 2019 18:53
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

bool: {
filter: {
term: {
_id: TASK_ID
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

taskManager really needs a get method :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that'd be nice 👍

@tsullivan
Copy link
Member

I'm still looking through it, but just a thought on the output. And this is maybe for @alexfrancoeur

Since the info is coming from a cache in ES, would it make sense to include a field for how old the cache is? Something like maps.cache_age_ms ?

I haven't done it for Telemetry for visualizations by type, but I kind of wish I brought up this quesiton then.

if (license && license.gis && !routesInitialized) {
routesInitialized = true;
initRoutes(server, license.uid);
initTelemetryCollection(server);
Copy link
Member

@tsullivan tsullivan Feb 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might not be necessary to keep initTelemetryCollection waiting for xpack_info license information, or the routesInitialized

As long as scheduling the built-in task waits for afterPluginsInit, which it does: https://github.com/elastic/kibana/pull/29346/files#diff-25f6c55fe3ca39b275e87048eb946ca8R16 I think you'd be able to call initTelemetryCollection directly from init

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking there was no point in registering for maps telemetry if there are no maps. Just one less thing to poll for the telemetry service. Do you disagree?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasoning sounds fine. I'd be a little cautious about the timing of when your afterPluginsInit declaration. If that happens too late in the server init, the Kibana server may have already processed all the callbacks in its queue: https://github.com/elastic/kibana/blob/f0cc432/src/server/plugins/wait_for_plugins_init.js

Looks like there would be an error thrown if that happens, but to be safe, I'd put that in up-front setup logic

Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome. don't know enough about telemetry itself, thanks @tsullivan for verifying that part

lgtm, but small suggestion for cleanup, while we're in the code. remove gis-* usage too.

xpackMainPlugin.info
.feature(thisPlugin.id)
.registerLicenseCheckResultsGenerator(checkLicense);
const thisPlugin = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thisPlugin variable is not necessary


async function getSavedObjects(savedObjectsClient) {
const gisMapsSavedObject = await savedObjectsClient.find({
type: 'gis-map'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be map

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

@alexfrancoeur
Copy link

@tsullivan I hadn't thought about that, definitely not opposed to introducing this metric. As long as it doesn't impact delivery time for FF 😄

@kindsun
Copy link
Contributor Author

kindsun commented Feb 4, 2019

@alexfrancoeur @tsullivan I've added a timeCaptured field to the telemetry. I figured that would cover what we're looking for and prevent an unnecessary date difference calculation on every polling cycle (i.e.- every few seconds).

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💔 Build Failed

@kindsun
Copy link
Contributor Author

kindsun commented Feb 4, 2019

retest

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@alexfrancoeur
Copy link

Sounds good, thanks @aaronjcaldwell!

Copy link
Member

@tsullivan tsullivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offered some food for thought about setup logic, but take it as you like :)

This code LGTM: I reviewed the diffs only


export function maps(kibana) {

return new kibana.Plugin({
require: ['kibana', 'elasticsearch', 'xpack_main', 'tile_map'],
require: ['kibana', 'elasticsearch', 'xpack_main', 'tile_map', 'task_manager'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, just to let you know, if someone needed to disable task manager, they would also have to disable the Maps plugin.

You could avoid that by putting the task stuff in x-pack/plugins/oss_telemetry

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some offline conversation and some code digging, I've decided to leave this as is for now with the understanding that we may need to rethink this dependency in the future. There shouldn't be a timing issue as the plugin spec requires dependencies be both enabled and initialized (

* @param {Array} [opts.require] the other plugins that this plugin
) however there is the issue of disabling the task manager effectively disabling the map. It may be possible to do a conditional require, however the condition would usually be on xpack.task_manager.enabled which is obtained from the server config at init time, trying to get this info at the point of require feels hacky. This might be a bigger issue of how to elegantly handle conditional requires in a broader way moving forward and could likely be tackled in the plugin spec.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@kindsun kindsun merged commit 55e7b18 into elastic:master Feb 5, 2019
kindsun added a commit to kindsun/kibana that referenced this pull request Feb 5, 2019
* Add basic framework for maps telemetry gathering

* Update mappings to cover required maps usage metrics

* Update telemetry to harvest from saved maps

* Consolidate. Clean up

* Harvest telemetry daily at midnight using task manager. Retrieve task mgr state in usage collector

* Organize, clean up

* Reorg

* Add usage collector tests. Add test utils

* Add maps telemetry tests to verify values. Multiple structure changes to support testing

* Review feedback

* More review feedback

* Add capture date/time to telemetry

* Change date to 'type: date'

* Review feedback

* Fix merge issue
kindsun added a commit that referenced this pull request Feb 5, 2019
* [Maps] Enh/gis telemetry (#29346)

* Add basic framework for maps telemetry gathering

* Update mappings to cover required maps usage metrics

* Update telemetry to harvest from saved maps

* Consolidate. Clean up

* Harvest telemetry daily at midnight using task manager. Retrieve task mgr state in usage collector

* Organize, clean up

* Reorg

* Add usage collector tests. Add test utils

* Add maps telemetry tests to verify values. Multiple structure changes to support testing

* Review feedback

* More review feedback

* Add capture date/time to telemetry

* Change date to 'type: date'

* Review feedback

* Fix merge issue

* Update telemetry test to account for maps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Deprecated-Use Team:Presentation]Team:Geo Former Team Label for Geo Team. Now use Team:Presentation enhancement New value added to drive a business result Feature:Telemetry v6.7.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants