Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit bd3f1d7

Browse files
authored
Merge pull request #1078 from atom/add-metrics
Add metrics logging for time to search in project
2 parents f9f1358 + 0104d9a commit bd3f1d7

File tree

6 files changed

+102
-5
lines changed

6 files changed

+102
-5
lines changed

docs/events.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Events specification
2+
3+
This document specifies all the data (along with the format) which gets sent from the Find and Replace package to the GitHub analytics pipeline. This document follows the same format and nomenclature as the [Atom Core Events spec](https://github.com/atom/metrics/blob/master/docs/events.md).
4+
5+
## Counters
6+
7+
Currently Find and Replace does not log any counter events.
8+
9+
## Timing events
10+
11+
#### Time to search on a project
12+
13+
* **eventType**: `find-and-replace-v1`
14+
* **metadata**
15+
16+
| field | value |
17+
|-------|-------|
18+
| `ec` | `time-to-search`
19+
| `ev` | Number of found results
20+
21+
## Standard events
22+
23+
Currently Find and Replace does not log any standard events.

lib/find.coffee

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ FindView = require './find-view'
99
ProjectFindView = require './project-find-view'
1010
ResultsModel = require './project/results-model'
1111
ResultsPaneView = require './project/results-pane'
12+
ReporterProxy = require './reporter-proxy'
13+
14+
metricsReporter = new ReporterProxy()
1215

1316
module.exports =
1417
activate: ({findOptions, findHistory, replaceHistory, pathsHistory}={}) ->
@@ -28,7 +31,7 @@ module.exports =
2831

2932
@findOptions = new FindOptions(findOptions)
3033
@findModel = new BufferSearch(@findOptions)
31-
@resultsModel = new ResultsModel(@findOptions)
34+
@resultsModel = new ResultsModel(@findOptions, metricsReporter)
3235

3336
@subscriptions.add atom.workspace.getCenter().observeActivePaneItem (paneItem) =>
3437
@subscriptions.delete @currentItemSub
@@ -132,6 +135,11 @@ module.exports =
132135
'find-and-replace:select-skip': (event) ->
133136
selectNextObjectForEditorElement(this).skipCurrentSelection()
134137

138+
consumeMetricsReporter: (service) ->
139+
metricsReporter.setReporter(service)
140+
new Disposable ->
141+
metricsReporter.unsetReporter()
142+
135143
consumeElementIcons: (service) ->
136144
getIconServices().setElementIcons service
137145
new Disposable ->

lib/project/results-model.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ class Result {
2727
}
2828

2929
module.exports = class ResultsModel {
30-
constructor (findOptions) {
30+
constructor (findOptions, metricsReporter) {
31+
this.metricsReporter = metricsReporter
3132
this.onContentsModified = this.onContentsModified.bind(this)
3233
this.findOptions = findOptions
3334
this.emitter = new Emitter()
@@ -172,6 +173,9 @@ module.exports = class ResultsModel {
172173

173174
const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore')
174175
const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter')
176+
177+
const startTime = Date.now()
178+
175179
this.inProgressSearchPromise = atom.workspace.scan(
176180
this.regex,
177181
{
@@ -195,8 +199,11 @@ module.exports = class ResultsModel {
195199
if (message === 'cancelled') {
196200
this.emitter.emit('did-cancel-searching')
197201
} else {
202+
const resultsSummary = this.getResultsSummary()
203+
204+
this.metricsReporter.sendSearchEvent(Date.now() - startTime, resultsSummary.matchCount)
198205
this.inProgressSearchPromise = null
199-
this.emitter.emit('did-finish-searching', this.getResultsSummary())
206+
this.emitter.emit('did-finish-searching', resultsSummary)
200207
}
201208
})
202209
}

lib/reporter-proxy.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports = class ReporterProxy {
2+
constructor () {
3+
this.reporter = null
4+
this.timingsQueue = []
5+
6+
this.eventType = 'find-and-replace-v1'
7+
}
8+
9+
setReporter (reporter) {
10+
this.reporter = reporter
11+
let timingsEvent
12+
13+
while ((timingsEvent = this.timingsQueue.shift())) {
14+
this.reporter.addTiming(this.eventType, timingsEvent.duration, timingsEvent.metadata)
15+
}
16+
}
17+
18+
unsetReporter () {
19+
delete this.reporter
20+
}
21+
22+
sendSearchEvent (duration, numResults) {
23+
const metadata = {
24+
ec: 'time-to-search',
25+
ev: numResults
26+
}
27+
28+
this._addTiming(duration, metadata)
29+
}
30+
31+
_addTiming (duration, metadata) {
32+
if (this.reporter) {
33+
this.reporter.addTiming(this.eventType, duration, metadata)
34+
} else {
35+
this.timingsQueue.push({duration, metadata})
36+
}
37+
}
38+
}

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
"versions": {
5858
"1.0.0": "consumeElementIcons"
5959
}
60+
},
61+
"metrics-reporter": {
62+
"versions": {
63+
"^1.1.0": "consumeMetricsReporter"
64+
}
6065
}
6166
},
6267
"providedServices": {

spec/results-model-spec.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const FindOptions = require("../lib/find-options");
66
const {beforeEach, it, fit, ffit, fffit} = require('./async-spec-helpers')
77

88
describe("ResultsModel", () => {
9-
let editor, resultsModel;
9+
let editor, resultsModel, reporterSpy;
1010

1111
beforeEach(async () => {
1212
atom.config.set("core.excludeVcsIgnoredPaths", false);
@@ -15,7 +15,10 @@ describe("ResultsModel", () => {
1515
atom.project.setPaths([path.join(__dirname, "fixtures/project")]);
1616

1717
editor = await atom.workspace.open("sample.js");
18-
resultsModel = new ResultsModel(new FindOptions());
18+
reporterSpy = {
19+
sendSearchEvent: jasmine.createSpy()
20+
}
21+
resultsModel = new ResultsModel(new FindOptions(), reporterSpy);
1922
});
2023

2124
describe("searching for a pattern", () => {
@@ -128,4 +131,17 @@ describe("ResultsModel", () => {
128131
expect(resultsModel.getMatchCount()).toBe(5);
129132
});
130133
});
134+
135+
describe("logging metrics", () => {
136+
it("logs the elapsed time and the number of results", async () => {
137+
await resultsModel.search('items', '*.js', '');
138+
139+
advanceClock(editor.buffer.stoppedChangingDelay)
140+
editor.getBuffer().destroy()
141+
result = resultsModel.getResult(editor.getPath())
142+
143+
expect(Number.isInteger(reporterSpy.sendSearchEvent.calls[0].args[0])).toBeTruthy()
144+
expect(reporterSpy.sendSearchEvent.calls[0].args[1]).toBe(6)
145+
});
146+
});
131147
});

0 commit comments

Comments
 (0)