Skip to content

Commit

Permalink
Telemetry (redwoodjs#3013)
Browse files Browse the repository at this point in the history
* Start of telemetry package

* Add telemetry middleware to yargs

* Attempt to time build command (doesn't work)

* Add telemetry url config value, refactor diagnostic info getting, capture nodeEnv

* Refactor, rename timer version

* Don't worry about second argument to slice

* Sanitize recorded command and strip paths from binaries in diagnostics

* Flatten info structure

* Switch to supabase/postgrest for submitting telemetry data

* Typescriptify telemetry package

* yarn.lock update

* Get around circular dependency on internal <-> structure

* Enforce row level security and inserts-only for anon user

* Updates snapshot with telemetry config

* Move telemetry to directory, use fork() for running send process

* Try to unref() to force child detach

* Swap fork to spawn

* Add error handling function

* Error telemetry looking good, adds 'build' type

* Adds errorTelemetry to all CLI commands that catch errors

* Adds ENV var for verbose telemetry

* Use netlify endpoint for telemetry

* Adds envinfo to internal

* import node-fetch

* Update config to real endpoint

* Update a few generators to use errorTelemetry

* Remove unused import

* Snapshot update

* Adds systeminformation package

* Pull cpu core count and total memory

* Move payload construction into separate function

* Support multiple replacement text, add tests for argv santization

* Removed unused variable, no response shown to user

* Remove unused import

* Set and cache UUID

* Set 'command' to empty string if no argv

* Send `create` telemetry event

* Moves telemetry to separate package

* CRA using new script in separate package

* Removes debugging

* Error handling in create

* sendTelemetry working with create

Thanks @dac09!

* Can set version from command args (yarn create doesn't have a version of Redwood installed so getInfo() can't find it)

* Adds ability to redact option flags

* Merge package updates

* Update telemetry version to match other packages

* Fix version requirement

* Fix envinfo version

* Update import from internal -> telemetry

* Update lint for all files in create-redwood-app/src

* Remove telemetry URL from config

* Moves telemetry tests

* Add a couple missing global.__dirname = __dirname

* Mock telemetry for all CLI commands

* Move telemetry mock to standalone file

* Add comment for eslint

* Update telemetry version

* Disable telemetry in e2e test app

* Disable telemetry in GH workflow runs

* Must return function call from timedTelemetry if disabled

* Update telemetry to 0.40.0

* Update lock

* Updates requirement of internal from telemetry

* Re-generate lock AGAIN

* Fix import

* Updated lock file

* Bad imports

* Remove debugging error throw

* yarn constraints --fix

* Update dependency versions in telemetry

* New URL for telemetry data post

* Bump telemetry to 0.41.0

* Fix dependency version

* Actually lock that update

* Set REDWOOD_CI env var during cypress testing

* Add redwoodCi to telemetry payload

* yarn install

* Update dependency versions

* Simplify REDWOOD_CI check

* Set REDWOOD_CI in execa defaults

* Turn telemetry back on for create, add to a couple more commands

* Disable telemetry for gitpod

* Remove DO_NOT_TRACK check for telemetry

* Try putting --no-telemetry flag back on e2e tests

* yarn install

* Update jest dependency in telemetry

* Remove --no-telemetry on create

* Put `--no-telemetry` back

* update yarn.lock

* add GitHub Action Telemetry Check

* to revert: testing non-detached process

* IDEs may not be present at all depending on environment (like CI)

* refactor setup deploy errorTelemetry

* remove env from E2E

* more options for REDWOOD_VERBOSE_TELEMETRY

* add telemetry CI commands

* lint fixes

* fix create-redwood-app telemetry; add CI verbose

* update yarn.lock and lint --fix

Co-authored-by: David Price <thedavid@thedavidprice.com>
  • Loading branch information
cannikin and thedavidprice authored Jan 19, 2022
1 parent d45c500 commit 4c69711
Show file tree
Hide file tree
Showing 50 changed files with 679 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ module.exports = {
'packages/api-server/src/**',
'packages/cli/src/**',
'packages/core/config/**',
'packages/create-redwood-app/src/create-redwood-app.js',
'packages/create-redwood-app/src/*.js',
'packages/internal/src/**',
'packages/prerender/src/**',
'packages/structure/src/**',
'packages/testing/src/**',
'packages/testing/config/**',
'packages/eslint-config/*.js',
'packages/record/src/**',
'packages/telemetry/src/**',
],
env: {
es6: true,
Expand Down
96 changes: 96 additions & 0 deletions .github/workflows/telemetry-benchmarks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Telemetry Checks and Benchmarks

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
cypress-run:
if: github.repository == 'redwoodjs/redwood'
strategy:
matrix:
os: ['ubuntu-latest']
node-version: ['14', '16']
fail-fast: true
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} | Node ${{ matrix.node-version }} latest
env:
REDWOOD_CI: 1
REDWOOD_VERBOSE_TELEMETRY: 1
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup node
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"

- name: Cache yarn
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-${{ hashFiles('yarn.lock') }}
restore-keys: |
yarn-
- name: Install dependencies and Build Framework
run: |
yarn install --immutable
yarn build:clean && yarn build:js
- name: Create a temporary directory
id: createpath
run: |
project_path=$(mktemp -d -t redwood.XXXXXX)
echo "::set-output name=project_path::$project_path"
framework_path=$(pwd)
echo "::set-output name=framework_path::$framework_path"
- name: Create Redwood Project
run: |
yarn babel-node packages/create-redwood-app/src/create-redwood-app.js ${{ steps.createpath.outputs.project_path }} --no-yarn-install
- name: Add Framework Dependencies to Project
run: |
yarn project:deps ${{ steps.createpath.outputs.project_path }}
- name: Run Project Yarn Install
run: |
yarn install
working-directory: ${{ steps.createpath.outputs.project_path }}

- name: Copy Framework Packages to Project
run: |
yarn project:copy ${{ steps.createpath.outputs.project_path }}
- name: Run `rw info`
run: |
yarn rw info
working-directory: ${{ steps.createpath.outputs.project_path }}

- name: Run `rw build`
run: |
yarn rw build
working-directory: ${{ steps.createpath.outputs.project_path }}

- name: Run "prisma migrate dev"
run: |
yarn rw prisma migrate dev --name ci-test
working-directory: ${{ steps.createpath.outputs.project_path }}

- name: Run "g page"
run: |
yarn rw g page home /
working-directory: ${{ steps.createpath.outputs.project_path }}

- name: Throw Error | Run `rw g sdl <model>`
run: |
yarn rw g sdl DoesNotExist
working-directory: ${{ steps.createpath.outputs.project_path }}
continue-on-error: true
1 change: 1 addition & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tasks:
before: |
export RWFW_PATH="/workspace/redwood"
export RWJS_DEV_API_URL="http://localhost"
export REDWOOD_DISABLE_TELEMETRY=1
init: |
cd /workspace/redwood
yarn install
Expand Down
3 changes: 2 additions & 1 deletion packages/auth/src/authClients/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const clerk = (client: Clerk): AuthClientClerk => {
client,
login: async (options?: SignInProps) =>
clerkClient(client)?.openSignIn(options || {}),
logout: async (options?: SignOutCallback) => clerkClient(client)?.signOut(options),
logout: async (options?: SignOutCallback) =>
clerkClient(client)?.signOut(options),
signup: async (options?: SignUpProps) =>
clerkClient(client)?.openSignUp(options || {}),
// Clerk uses the session ID PLUS the __session cookie.
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@redwoodjs/internal": "0.41.0",
"@redwoodjs/prerender": "0.41.0",
"@redwoodjs/structure": "0.41.0",
"@redwoodjs/telemetry": "0.41.0",
"boxen": "5.1.2",
"camelcase": "6.3.0",
"chalk": "4.1.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/__tests__/type-check.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jest.mock('concurrently', () =>
})
)

import '../../lib/mockTelemetry'

let mockedRedwoodConfig = {
api: {},
web: {},
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import terminalLink from 'terminal-link'

import { buildApi, loadAndValidateSdls } from '@redwoodjs/internal'
import { detectPrerenderRoutes } from '@redwoodjs/prerender/detection'
import { timedTelemetry, errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths } from '../lib'
import c from '../lib/colors'
Expand Down Expand Up @@ -191,9 +192,12 @@ export const handler = async ({
})

try {
await jobs.run()
await timedTelemetry(process.argv, { type: 'build' }, async () => {
await jobs.run()
})
} catch (e) {
console.log(c.error(e.message))
errorTelemetry(process.argv, e.message)
process.exit(1)
}
}
3 changes: 3 additions & 0 deletions packages/cli/src/commands/dataMigrate/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import fs from 'fs-extra'
import Listr from 'listr'
import terminalLink from 'terminal-link'

import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths } from '../../lib'
import c from '../../lib/colors'

Expand Down Expand Up @@ -90,6 +92,7 @@ export const handler = async () => {
try {
await tasks.run()
} catch (e) {
errorTelemetry(process.argv, e.message)
console.error(c.error(e.message))
process.exit(e?.exitCode || 1)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/dataMigrate/up.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import VerboseRenderer from 'listr-verbose-renderer'
import terminalLink from 'terminal-link'

import { registerApiSideBabelHook } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths } from '../../lib'
import c from '../../lib/colors'
Expand Down Expand Up @@ -173,6 +174,7 @@ export const handler = async () => {
} catch (e) {
await db.$disconnect()
report(counters)
errorTelemetry(process.argv, e.message)
process.exit(e?.exitCode || 1)
}
}
11 changes: 11 additions & 0 deletions packages/cli/src/commands/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import concurrently from 'concurrently'
import terminalLink from 'terminal-link'

import { getConfig, getConfigPath, shutdownPort } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths } from '../lib'
import c from '../lib/colors'
Expand Down Expand Up @@ -60,12 +61,17 @@ export const handler = async ({
schema: rwjsPaths.api.dbSchema,
})
} catch (e) {
errorTelemetry(
process.argv,
`Error generating prisma client: ${e.message}`
)
console.error(c.error(e.message))
}

try {
await shutdownPort(getConfig().api.port)
} catch (e) {
errorTelemetry(process.argv, `Error shutting down "api": ${e.message}`)
console.error(
`Error whilst shutting down "api" port: ${c.error(e.message)}`
)
Expand All @@ -76,6 +82,7 @@ export const handler = async ({
try {
await shutdownPort(getConfig().web.port)
} catch (e) {
errorTelemetry(process.argv, `Error shutting down "web": ${e.message}`)
console.error(
`Error whilst shutting down "web" port: ${c.error(e.message)}`
)
Expand Down Expand Up @@ -130,6 +137,10 @@ export const handler = async ({
)
result.catch((e) => {
if (typeof e?.message !== 'undefined') {
errorTelemetry(
process.argv,
`Error concurrently starting sides: ${e.message}`
)
console.error(c.error(e.message))
process.exit(1)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
global.__dirname = __dirname
import path from 'path'

// Load shared mocks
import '../../../../lib/test'

import path from 'path'

import * as functionGenerator from '../function'

// Should be refactored as it's repeated
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/commands/generate/function/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import camelcase from 'camelcase'
import Listr from 'listr'
import terminalLink from 'terminal-link'

import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths, transformTSToJS, writeFilesTask } from '../../../lib'
import c from '../../../lib/colors'
import { yargsDefaults } from '../../generate'
Expand Down Expand Up @@ -151,6 +153,7 @@ export const handler = async ({ name, force, ...rest }) => {
)
console.info('')
} catch (e) {
errorTelemetry(process.argv, e.message)
console.error(c.error(e.message))
process.exit(e?.exitCode || 1)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/generate/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import pascalcase from 'pascalcase'
import terminalLink from 'terminal-link'

import { ensurePosixPath, getConfig } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import { generateTemplate, getPaths, writeFilesTask } from '../../lib'
import c from '../../lib/colors'
Expand Down Expand Up @@ -183,6 +184,7 @@ export const createYargsForComponentGeneration = ({

await tasks.run()
} catch (e) {
errorTelemetry(process.argv, e.message)
console.error(c.error(e.message))
process.exit(e?.exitCode || 1)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/generate/page/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Listr from 'listr'
import pascalcase from 'pascalcase'

import { getConfig, generate as generateTypes } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import {
addRoutesToRouterTask,
Expand Down Expand Up @@ -243,6 +244,7 @@ export const handler = async ({
try {
await tasks.run()
} catch (e) {
errorTelemetry(process.argv, e.message)
console.error(c.error(e.message))
process.exit(e?.exitCode || 1)
}
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/commands/generate/script/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import path from 'path'
import Listr from 'listr'
import terminalLink from 'terminal-link'

import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths, writeFilesTask } from '../../../lib'
import c from '../../../lib/colors'
import { yargsDefaults } from '../../generate'
Expand Down Expand Up @@ -83,6 +85,7 @@ export const handler = async ({ force, ...args }) => {
try {
await tasks.run()
} catch (e) {
errorTelemetry(process.argv, e.message)
console.log(c.error(e.message))
process.exit(1)
}
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/generate/sdl/sdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Listr from 'listr'
import terminalLink from 'terminal-link'

import { getConfig, generate as generateTypes } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import {
generateTemplate,
Expand Down Expand Up @@ -240,6 +241,7 @@ export const handler = async ({ model, crud, force, tests, typescript }) => {

await tasks.run()
} catch (e) {
errorTelemetry(process.argv, e.message)
console.error(c.error(e.message))
process.exit(e?.exitCode || 1)
}
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/commands/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import VerboseRenderer from 'listr-verbose-renderer'
import { getPaths } from '@redwoodjs/internal'
import { runPrerender, writePrerenderedHtmlFile } from '@redwoodjs/prerender'
import { detectPrerenderRoutes } from '@redwoodjs/prerender/detection'
import { errorTelemetry } from '@redwoodjs/telemetry'

import c from '../lib/colors'

Expand Down Expand Up @@ -105,6 +106,8 @@ export const getTasks = async (dryrun, routerPathFilter = null) => {
}" ${c.info('-'.repeat(10))}`
)

errorTelemetry(process.argv, `Error prerendering: ${e.message}`)

console.error(c.error(e.stack))
console.log()

Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/prisma.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import boxen from 'boxen'
import execa from 'execa'

import { getPaths } from '@redwoodjs/internal'
import { errorTelemetry } from '@redwoodjs/telemetry'

import c from '../lib/colors'

Expand Down Expand Up @@ -92,6 +93,7 @@ export const handler = async ({ _, $0, commands = [], ...options }) => {
printWrapInfo()
}
} catch (e) {
errorTelemetry(process.argv, `Error generating prisma client: ${e.message}`)
process.exit(e?.exitCode || 1)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import fs from 'fs'

import '../../../../lib/mockTelemetry'

import { addConfigToApp } from '../auth'

jest.mock('../../../../lib', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
global.__dirname = __dirname

import '../../../../lib/mockTelemetry'

jest.mock('fs')
jest.mock('../../../../lib', () => ({
getPaths: () => ({
Expand Down
Loading

0 comments on commit 4c69711

Please sign in to comment.