Skip to content

Views for metrics v2-v3#159

Draft
antoinehashbang wants to merge 10 commits intomasterfrom
antoine/views_metrics_v2_v3
Draft

Views for metrics v2-v3#159
antoinehashbang wants to merge 10 commits intomasterfrom
antoine/views_metrics_v2_v3

Conversation

@antoinehashbang
Copy link
Contributor

@antoinehashbang antoinehashbang force-pushed the antoine/views_metrics_v2_v3 branch from 051e127 to e3c0d39 Compare July 15, 2021 14:46
Base automatically changed from lize/metrics-v3 to master July 20, 2021 13:56
@antoinehashbang antoinehashbang force-pushed the antoine/views_metrics_v2_v3 branch from e3c0d39 to 32312ad Compare July 21, 2021 11:38
@liZe liZe added the alembic-metrics The pull request includes an Alembic deployment for metrics label Jul 26, 2021
@liZe liZe force-pushed the antoine/views_metrics_v2_v3 branch from 5fe4923 to 85619db Compare July 27, 2021 14:16
@liZe
Copy link
Contributor

liZe commented Jul 27, 2021

@wjt As discussed earlier, this branch is not ready to be merged, but I’d appreciate a "quick" review to check that everything is OK so far.

What’s missing and/or wrong:

  • conflict (fixed),
  • tests and lint,
  • strange commits, rebase required,
  • migration including V2+V3 views is not included,
  • union_all in queries requires columns, not tables,
  • channel_id needs to replace channel columns, with a solution to get both V2 and V3 channels.

liZe added 5 commits July 27, 2021 16:27
This commit is broken and will be fixed later:
- the Alembic migration is not included
- union_all doesn’t accept tables (requires columns)
@liZe liZe force-pushed the antoine/views_metrics_v2_v3 branch from 85619db to 482c6b3 Compare July 27, 2021 14:27
Comment on lines +265 to +266
# Add properties needed to reference views in other views
cls.c, cls.self_group = table.c, table.self_group
Copy link
Member

Choose a reason for hiding this comment

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

I'll have to take your word for it that this is right :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should override the __getattr__ method of View to get the attributes of the table when they exist, but that’s not necessary now when everything works with only these two attributes.

__tablename__ = 'monthly_session_time_v3'
__event_uuid__ = '8023ae8e-f0c7-4fee-bc00-2d6b28061fce'
__payload_type__ = None
from .events import * # noqa: F403, F401
Copy link
Member

Choose a reason for hiding this comment

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

Please can we have separate commits for:

  • move the events (without modification) from __init__.py to events.py
  • move the existing views (without modification) from __init__.py to views.py

Comment on lines 47 to 50
Machine.image_id,
Machine.location.label('site'),
Machine.dualboot.label('dual_boot'),
Machine.live
Copy link
Member

Choose a reason for hiding this comment

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

As discussed elsewhere: it would be ideal to instead have a channel_id which refers to a row in channel_v3. This might work like this (conceptually)

  • before updating these views, select distinct image_id, location, dualboot, live, … from metrics_machine, and ensure all such rows are in channel_v3. To my slight surprise there are "only" 2358 distinct such rows. (There are almost a million distinct metrics_machine rows.)
  • in this query, join to ChannelV3 on those 4 fields, and add ChannelV3.id.label("channel_id") to the query() list.

Comment on lines 57 to 58
).outerjoin(
OSVersion
Copy link
Member

Choose a reason for hiding this comment

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

Looking at the generated query, this is joining os_version.request_id = launched_existing_equivalent_flatpak.request_id. I think the reason for distinct() below is that there may be multiple os_version events in the same request as any other given request? The other problem is that there will often be no os_version event in the same request as events like launched_existing_equivalent_flatpak which are recorded at basically arbitrary times while the system is in use. (os_version is recorded when the machine boots; and metrics are uploaded every hour; so if launched_existing_equivalent_flatpak is recorded more than an hour after the machine boots, and more than an hour before it next reboots, then there will not be an os_version in the same request.)

Is this join significant in the query plans, particularly for the views that take longer to build? If so, we could just set os_version to NULL, in the knowledge that NULL means "older than eos4". Not ideal but that's already the status quo with v2, it's hard to get the OS version for any given event.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the reason for distinct() below is that there may be multiple os_version events in the same request as any other given request?

Exactly.

The other problem is that there will often be no os_version event in the same request as events like launched_existing_equivalent_flatpak which are recorded at basically arbitrary times while the system is in use.

That’s why there’s an outer join, I think that it solves this problem.

Is this join significant in the query plans, particularly for the views that take longer to build?

Unfortunately, I don’t think so.

Comment on lines 53 to 56
).outerjoin(
Request
).outerjoin(
Machine, Request.machine_id == Machine.machine_id
Copy link
Member

Choose a reason for hiding this comment

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

Why outerjoin? There should always be exactly one Machine per Request, and one Request per LaunchedEquivalentExistingFlatpakV2, so can it not be an inner join?

Copy link
Contributor

Choose a reason for hiding this comment

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

Why outerjoin? There should always be exactly one Machine per Request, and one Request per LaunchedEquivalentExistingFlatpakV2, so can it not be an inner join?

That’s what I thought, but that’s not the case with production data. There are so many rows that it’s hard to find the data where there’s something wrong. The difference was small, as far as I can remember, so using join would probably be OK too.

Comment on lines +615 to +616
class UpdaterFailureView(View):
__tablename__ = 'updater_failure_view'
Copy link
Member

Choose a reason for hiding this comment

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

I'm not very keen on the "view" suffix here. Similarly the _view_v2 suffix is a bit opaque.

Perhaps…

  • updater_failure: real V2 data
  • updater_failure_v3: real V3 data
  • updater_failure_v2_as_v3: materialized view of V2 data in V3 format
  • updater_failure_all: combined view of v2 & v3 data

I'm not all that keen on those names either and have asked on #os for other suggestions :)

(Here I am about to overcomplicate things, probably, but… we could use a separate postgresql schema to namespace these views. All the current views and tables are in public. Maybe a combined schema containing updater_failure (which is the combined view of v2 and v3 data) and a v2_as_v3 schema containing the materialized view? As I type this, I think this would actually be more confusing.)

Copy link
Member

Choose a reason for hiding this comment

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

@dbnicholson thinks that either updater_failure_v2_as_v3 or updater_failure_view_v2 is fine for the materialized view, and updater_failure_all is OK for the combined view. From our Slack:

i think that naming makes sense, although i don't believe A actually has to change. the events did come from the v2 protocol. the fact that their being views in the v3 format is IMO an implementation detail of v3 being the current format. i don't believe you want to keep viewing the v2 events in v2 format

Comment on lines +403 to +404


Copy link
Member

Choose a reason for hiding this comment

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

I guess these are just not yet implemented but this branch is missing the 2 × 3 tables to turn old sequence events into new aggregate events.

Copy link
Contributor

Choose a reason for hiding this comment

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

They’re not created yet, that’s right.

@liZe
Copy link
Contributor

liZe commented Jul 29, 2021

I wish I had some extra time to finally merge this PR…

I’ve marked as "resolved" the comments of @wjt’s review that are now resolved. Here’s what’s missing:

  • using channel_id instead of the channel attributes;
  • renaming views;
  • adding aggregate events;
  • (optional) overriding View.__getattr__ to wrap more table attributes;
  • and finally, rebasing commits to get a nice history.

Don’t hesitate to ping me in this PR if you need anything!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

alembic-metrics The pull request includes an Alembic deployment for metrics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants