Skip to content

Commit

Permalink
feat(core): add telemetry scaffolding to Studio (#5503)
Browse files Browse the repository at this point in the history
* feat(core): add telemetry scaffolding to Studio

* fix(telemetry): log whether document was published for the first time, and published immediately after created
  • Loading branch information
bjoerge authored Jan 23, 2024
1 parent 39babbf commit 66b88f7
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/@sanity/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
},
"dependencies": {
"@babel/traverse": "^7.23.5",
"@sanity/telemetry": "^0.7.5",
"@sanity/telemetry": "^0.7.6",
"chalk": "^4.1.2",
"esbuild": "^0.19.8",
"esbuild-register": "^3.4.1",
Expand Down
4 changes: 3 additions & 1 deletion packages/sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
"@sanity/portable-text-editor": "3.25.0",
"@sanity/presentation": "1.7.0",
"@sanity/schema": "3.25.0",
"@sanity/telemetry": "^0.7.5",
"@sanity/telemetry": "^0.7.6",
"@sanity/types": "3.25.0",
"@sanity/ui": "^2.0.0",
"@sanity/util": "3.25.0",
Expand All @@ -212,6 +212,7 @@
"@types/speakingurl": "^13.0.3",
"@types/use-sync-external-store": "^0.0.5",
"@vitejs/plugin-react": "^4.2.0",
"arrify": "^1.0.1",
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
"classnames": "^2.2.5",
Expand Down Expand Up @@ -289,6 +290,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.0.16",
"@types/arrify": "^1.0.4",
"@types/connect-history-api-fallback": "^1.5.2",
"@types/lodash": "^4.14.149",
"@types/log-symbols": "^2.0.0",
Expand Down
9 changes: 6 additions & 3 deletions packages/sanity/src/core/studio/StudioProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from './screens'
import {WorkspaceLoader} from './workspaceLoader'
import {WorkspacesProvider} from './workspaces'
import {StudioTelemetryProvider} from './StudioTelemetryProvider'

Refractor.registerLanguage(bash)
Refractor.registerLanguage(javascript)
Expand Down Expand Up @@ -54,9 +55,11 @@ export function StudioProvider({
}: StudioProviderProps) {
const _children = (
<WorkspaceLoader LoadingComponent={LoadingBlock} ConfigErrorsComponent={ConfigErrorsScreen}>
<LocaleProvider>
<ResourceCacheProvider>{children}</ResourceCacheProvider>
</LocaleProvider>
<StudioTelemetryProvider config={config}>
<LocaleProvider>
<ResourceCacheProvider>{children}</ResourceCacheProvider>
</LocaleProvider>
</StudioTelemetryProvider>
</WorkspaceLoader>
)

Expand Down
52 changes: 52 additions & 0 deletions packages/sanity/src/core/studio/StudioTelemetryProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {createBatchedStore, createSessionId} from '@sanity/telemetry'
import {TelemetryProvider} from '@sanity/telemetry/react'
import React, {ReactNode, useEffect, useMemo} from 'react'
import arrify from 'arrify'
import {SANITY_VERSION} from '../version'
import {Config} from '../config'
import {useClient} from '../hooks'

const sessionId = createSessionId()

// Wrap the app in a TelemetryProvider
// This will enable usage of the `useTelemetry()` hook
export function StudioTelemetryProvider(props: {children: ReactNode; config: Config}) {
const client = useClient({apiVersion: 'v2023-12-18'})

const projectId = client.config().projectId
const store = useMemo(() => {
return createBatchedStore(sessionId, {
// submit any pending events every <n> ms
flushInterval: 30000,

// implements user consent resolving
resolveConsent: () => client.request({uri: '/intake/telemetry-status'}),

// implements sending events to backend
sendEvents: (batch) =>
client.request({
uri: '/intake/batch',
method: 'POST',
json: true,
body: {projectId, batch},
}),
// opts into a different strategy for sending events when the browser close, reload or navigate away from the current page
sendBeacon: (batch) =>
navigator.sendBeacon(client.getUrl('/intake/batch'), JSON.stringify({projectId, batch})),
})
}, [client, projectId])

useEffect(() => {
store.logger.updateUserProperties({
studioVersion: SANITY_VERSION,
plugins: arrify(props.config).flatMap(
(config) =>
config.plugins?.flatMap((plugin) => ({
name: plugin.name,
})) || [],
),
})
}, [props.config, store.logger])

return <TelemetryProvider store={store}>{props.children}</TelemetryProvider>
}
12 changes: 12 additions & 0 deletions packages/sanity/src/structure/documentActions/PublishAction.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {CheckmarkIcon, PublishIcon} from '@sanity/icons'
import {isValidationErrorMarker} from '@sanity/types'
import React, {useCallback, useEffect, useState} from 'react'
import {useTelemetry} from '@sanity/telemetry/react'
import {useDocumentPane} from '../panes/document/useDocumentPane'
import {structureLocaleNamespace, type StructureLocaleResourceKeys} from '../i18n'

import {DocumentPublished} from './__telemetry__/documentActions.telemetry'
import {
DocumentActionComponent,
InsufficientPermissionsMessage,
Expand Down Expand Up @@ -122,7 +125,13 @@ export const PublishAction: DocumentActionComponent = (props) => {
return () => clearTimeout(timer)
}, [changesOpen, publishState, hasDraft, onHistoryOpen])

const telemetry = useTelemetry()

const handle = useCallback(() => {
telemetry.log(DocumentPublished, {
publishedImmediately: !draft?._createdAt,
previouslyPublished: Boolean(published),
})
if (
syncState.isSyncing ||
validationStatus.isValidating ||
Expand All @@ -133,6 +142,9 @@ export const PublishAction: DocumentActionComponent = (props) => {
doPublish()
}
}, [
telemetry,
draft?._createdAt,
published,
syncState.isSyncing,
validationStatus.isValidating,
validationStatus.revision,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {defineEvent} from '@sanity/telemetry'

interface DocumentPublishedInfo {
/**
* The document was created and published straight away
*/
publishedImmediately: boolean

/**
* The document had a previously published version when it was published
*/
previouslyPublished: boolean
}
export const DocumentPublished = defineEvent<DocumentPublishedInfo>({
name: 'Document Published',
version: 1,
description: 'User clicked the "Publish" button in the document pane',
})
13 changes: 9 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3773,10 +3773,10 @@
dependencies:
"@sanity/uuid" "3.0.2"

"@sanity/telemetry@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@sanity/telemetry/-/telemetry-0.7.5.tgz#e9c39d35a55892ec230654f33d008f75aa2a398a"
integrity sha512-lY1Lmt2zl9YIIXO2bAFGXR542ovpn8jmLmIos1mQU4D+ItbZsPBxt9g72bJCsUZ7yodMf2K4t4Tp7BTv0as9sg==
"@sanity/telemetry@^0.7.7":
version "0.7.7"
resolved "https://registry.yarnpkg.com/@sanity/telemetry/-/telemetry-0.7.7.tgz#7905bb51aaf4217363242d229618ca65a0ec773f"
integrity sha512-YUoAMrl0XEf5C4Jt0n+wmJAR7gDrraic3u7yxog0U2QukgeOn9BDhXF5rF9jMuDllGZmUbBaFq+mh5sW/tACWw==
dependencies:
lodash "^4.17.21"
react "^18.2.0"
Expand Down Expand Up @@ -4067,6 +4067,11 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.1.tgz#3286741fb8f1e1580ac28784add4c7a1d49bdfbc"
integrity sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==

"@types/arrify@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/arrify/-/arrify-1.0.4.tgz#0b7bc8d80e29db296e8e0c59e009274a03dcf783"
integrity sha512-63nK8r8jvEVJ1r0ENaY9neB1wDzPHFYAzKiIxPawuzcijEX8XeOywwPL8fkSCwiTIYop9MSh+TKy9L2ZzTXV6g==

"@types/babel__core@^7.1.14", "@types/babel__core@^7.20.4":
version "7.20.4"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.4.tgz#26a87347e6c6f753b3668398e34496d6d9ac6ac0"
Expand Down

2 comments on commit 66b88f7

@vercel
Copy link

@vercel vercel bot commented on 66b88f7 Jan 23, 2024

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

performance-studio – ./

performance-studio-git-next.sanity.build
performance-studio.sanity.build

@vercel
Copy link

@vercel vercel bot commented on 66b88f7 Jan 23, 2024

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

test-studio – ./

test-studio-git-next.sanity.build
test-studio.sanity.build

Please sign in to comment.