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

Add source to analytics events. #2750

Merged
merged 6 commits into from
Sep 15, 2023
Merged

Conversation

mitchell-as
Copy link
Contributor

@mitchell-as mitchell-as commented Sep 12, 2023

TaskDX-2145 We identify State Tool traffic as State Tool traffic

This allows for differentiation between state tool, offline installer, executor, etc.

This allows for differentiation between state tool, offline installer, executors, etc.
Comment on lines -40 to -41
const AnalyticsCat = "installer"
const AnalyticsFunnelCat = "installer-funnel"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved into analytics/constants.go

@mitchell-as mitchell-as requested a review from Naatan September 12, 2023 18:31
@mitchell-as mitchell-as marked this pull request as ready for review September 12, 2023 18:31
Copy link
Member

@Naatan Naatan left a comment

Choose a reason for hiding this comment

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

I think we should set this at construction time. We would never want to modify this on a per-event basis.

Also note with the svc that it handles two types of analytics:

Also improve forwarding events on behalf of executors.
@@ -97,7 +97,7 @@ func (w *Watcher) check() {

func (w *Watcher) RecordUsage(e entry) {
logging.Debug("Recording usage of %s (%d)", e.Exec, e.PID)
w.an.Event(anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, e.Dims)
w.an.EventWithSource(anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, anaConst.SrcExecutor, e.Dims)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks to me like all heartbeats come from executors, so that's why the source is this and not State Tool.

Copy link
Member

Choose a reason for hiding this comment

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

Good call! I forgot about that caveat.

@mitchell-as
Copy link
Contributor Author

Good call with putting source in the analytics client. We still need some wiggle room to differentiate between state tool and executors (particularly in the runtime area), so state-svc cannot assume anForClient is always coming from State Tool, and instead forwards on behalf of the incoming source (currently State Tool or Executor).

If you don't care to differentiate, let me know and I'll drop all that special handling. Or if you have another idea, let me know.

@mitchell-as mitchell-as requested a review from Naatan September 13, 2023 16:58
Copy link
Member

@Naatan Naatan left a comment

Choose a reason for hiding this comment

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

Looks great! In addition to the one case I flagged for executor handling, I think we should also have our analytics integration tests specifically check for it.

IIRC the analytics tests are already triggering state tool events as well as executor events, so with the data we're already generating we could assert that they have the expected source set.

pkg/platform/runtime/analytics/analytics.go Outdated Show resolved Hide resolved
)

var isExecutor bool

func init() {
if osutils.Executable() == constants.StateExecutorCmd {
isExecutor = true
if isExec, err := executors.IsExecutor(osutils.Executable()); err == nil {
Copy link
Member

Choose a reason for hiding this comment

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

As I said executors do not use the analytics package directly, so I don't think we need this?

Copy link
Contributor Author

@mitchell-as mitchell-as Sep 14, 2023

Choose a reason for hiding this comment

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

Executors can trigger runtime setup/use, right? That will send out analytics requests to state-svc, which should then forward them to GA: https://github.com/ActiveState/cli/pull/2750/files#diff-d6507bff98aa2549ce60b737f856f84e7a24e20bf39fef4a7ba6f05adf62ffe7R100-R103

Or am I missing something? When I checked the analytics int test event files, I'm seeing runtime-use:attempt, runtime-debug:download, and runtime-debug:success events for executors (e.g. python --version). This is what I expected to see.

Copy link
Member

Choose a reason for hiding this comment

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

That's right, but this code is checking the current executable. There is never a scenario in which an executor invokes the analytics code (whether sync or async) directly. Instead they talk directly to the svc without the analytics library. The svc then uses its analytics library to report the event.

In other words; I don't believe there is a scenario in which this conditional evaluates to true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, you're right. I went through a debugger and that code does not appear to be hit. I've removed it.

fmt.Sprintf("output:\n%s\n%s",
cp.Snapshot(), ts.DebugLogs()))

heartbeatInitialCount := countEvents(events, anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat)
heartbeatInitialCount := countEvents(events, anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, anaConst.SrcExecutor)
Copy link
Member

Choose a reason for hiding this comment

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

Can we also assert here that we got both executor and state tool heartbeats?

ie. the state activate should've triggered heartbeats from the state tool, whereas the executor would've triggered it from the executor.

Copy link
Contributor Author

@mitchell-as mitchell-as Sep 14, 2023

Choose a reason for hiding this comment

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

Okay, so my comment here is not valid, right? #2750 (comment) I want to confirm before I spend time on this.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry that's my bad. Your comment there is indeed incorrect, I should've known that but I guess I wasn't thinking it through.

@mitchell-as mitchell-as requested a review from Naatan September 14, 2023 18:18
Copy link
Member

@Naatan Naatan left a comment

Choose a reason for hiding this comment

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

See comments.

Executors should not invoke this code directly, so there should be no analytics source confusion.
@mitchell-as mitchell-as requested a review from Naatan September 14, 2023 19:06
Copy link
Member

@Naatan Naatan left a comment

Choose a reason for hiding this comment

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

Looks good! I think you missed this comment though: #2750 (comment)

@mitchell-as
Copy link
Contributor Author

Sorry about that. Too many double negatives. I got confused and thought the opposite of what you were thinking :S

Comment on lines 102 to 106
source := anaConst.SrcExecutor
if filepath.Base(e.Exec) == constants.StateCmd+osutils.ExeExt {
source = anaConst.SrcStateTool
}
w.an.EventWithSource(anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, source, e.Dims)
Copy link
Member

Choose a reason for hiding this comment

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

This feels too error prone to me. Could we instead add the source as an argument for the ReportRuntimeUsage resolver on the svc?

The only place executors call this is here:

_, err = resolver.ReportRuntimeUsage(context.Background(), pidNum, hb.ExecPath, dimsJSON)

Any other place would be state tool. I'd be fine defaulting to state tool if the source is empty.

@mitchell-as
Copy link
Contributor Author

The change got a bit involved since there's graphql involved, so let me know if you had something else in mind.

@mitchell-as mitchell-as requested a review from Naatan September 15, 2023 16:59
Copy link
Member

@Naatan Naatan left a comment

Choose a reason for hiding this comment

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

Looks great!

@mitchell-as mitchell-as merged commit 1335957 into version/0-41-0-RC1 Sep 15, 2023
6 checks passed
@mitchell-as mitchell-as deleted the mitchell/dx-2145 branch September 15, 2023 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants