安装 Blipit

选择你的应用所用的技术。你会看到该指南中的确切步骤,点一下即可在 app.blipit.io 中查看已填好你自己密钥的版本。

1选择你的技术栈

2任意网站 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 npm install @blipit/browser

1获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

2使用 npm

在入口文件中、应用渲染之前,用公钥调用一次 init。使用 Vite(React、Vue、Svelte)时,把密钥以 VITE_BLIPIT_KEY 保存在 .env 中;只有 VITE_ 开头的变量会传到浏览器,而且开发服务器只在启动时读取 .env。

sh
npm install @blipit/browser
.env
VITE_BLIPIT_KEY=blipit_pk_your_public_key
src/main.js
import * as Blipit from "@blipit/browser";

Blipit.init({
  key: import.meta.env.VITE_BLIPIT_KEY,
  environment: import.meta.env.MODE,
  release: "2026.09.28",
  replay: { onErrorSampleRate: 1 },
});

3不用打包器:一个 script 标签

把这段代码粘贴到每个页面的 <head> 中,或粘贴到你所用平台的自定义代码位置,并写入你的公钥。这没有问题:公钥只能发送事件。

html
<script src="https://blipit.io/sdk/blipit.js"></script>
<script>
  Blipit.init({ key: "blipit_pk_your_public_key", environment: "production", release: "2026.09.28", replay: { onErrorSampleRate: 1 } });
</script>

4不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

5告诉 Blipit 用户是谁(可选)

登录后附加用户信息,问题就能显示受影响的人,回放也可以按用户查找。

js
Blipit.setUser({ id: "42", email: "ana@example.com" });

6React、Vue、Angular 和 Svelte:上报已捕获的错误

框架会在浏览器看到之前捕获组件内部的错误,所以也要把这些错误传给 Blipit。其他地方未捕获的错误会自动上报。

React 19(src/main.tsx)
createRoot(document.getElementById("root")!, {
  onCaughtError: (error) => Blipit.captureException(error),
  onUncaughtError: (error) => Blipit.captureException(error),
}).render(<App />);
或者,React 18 及更早版本:错误边界
class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { failed: boolean }> {
  state = { failed: false };
  static getDerivedStateFromError() {
    return { failed: true };
  }
  componentDidCatch(error: Error) {
    Blipit.captureException(error);
  }
  render() {
    return this.state.failed ? <p>Something went wrong.</p> : this.props.children;
  }
}
Vue(src/main.ts)
const app = createApp(App);
app.config.errorHandler = (err) => Blipit.captureException(err);
app.mount("#app");
Angular(app.config.ts)
import { ErrorHandler } from "@angular/core";
import * as Blipit from "@blipit/browser";

class BlipitErrorHandler implements ErrorHandler {
  handleError(error: unknown) {
    Blipit.captureException(error);
    console.error(error);
  }
}

export const appConfig = { providers: [{ provide: ErrorHandler, useClass: BlipitErrorHandler }] };
SvelteKit(src/hooks.client.ts)
import * as Blipit from "@blipit/browser";
import type { HandleClientError } from "@sveltejs/kit";

export const handleError: HandleClientError = ({ error }) => {
  Blipit.captureException(error);
};

7错误报告:“报告问题”按钮

SDK 使用你的公钥启动后,每个页面的右下角就会出现一个“报告问题”按钮,使用访客的语言。点击后会打开报告器:一张可标注的页面截图、一个元素选择器、可选的屏幕录制,以及标题和描述。你可以像下面这样在代码中更改位置、样式、文字、颜色和快捷键,也可以在 app.blipit.io 的“项目设置”›“错误报告小组件”中一次性为所有网站更改;代码中的选项优先。“错误报告按钮”指南用截图和在线演示展示了每个选项。

js
Blipit.init({
  key: import.meta.env.VITE_BLIPIT_KEY,
  feedbackWidget: {
    position: "bottom-left",
    style: "icon",
    text: "Report Issue",
    color: "#E11D48",
    shortcut: "ctrl+shift+b",
  },
});
默认的“报告问题”按钮,位于右下角。
默认的“报告问题”按钮,位于右下角。
报告器:已标注的截图、标题和问题描述。
报告器:已标注的截图、标题和问题描述。

8从你自己的按钮打开报告器

要在你自己的页眉或菜单中放置“报告问题”按钮,请使用官方按钮:Blipit.reportButton() 会返回一个现成的按钮,带有 Blipit 图标和访客语言的“报告问题”;React 应用可以渲染 @blipit/nextjs/react 中的 <BlipitReportButton />(npm install @blipit/nextjs)。想用自己的设计?从任意点击处理函数调用 openReport(),或用 attachReport(element) 绑定一个已有的元素。两种方式打开的报告窗口都与悬浮按钮完全相同。Blipit 图标只能放在“报告问题”旁边使用,就像官方按钮那样。

官方按钮,纯 HTML
<nav id="help-menu"></nav>
<script>
  document.getElementById("help-menu").append(Blipit.reportButton());
</script>
官方按钮,React
import { BlipitReportButton } from "@blipit/nextjs/react";

export function Header() {
  return (
    <header>
      <a href="/">Acme</a>
      <BlipitReportButton variant="outline" size="sm" />
    </header>
  );
}
官方按钮,Vue
<script setup>
import { onMounted, ref } from "vue";
import { reportButton } from "@blipit/browser";

const slot = ref();
onMounted(() => slot.value.append(reportButton({ variant: "outline", size: "sm" })));
</script>

<template>
  <span ref="slot"></span>
</template>
纯 HTML
<button id="report-issue">Report Issue</button>
<script>
  Blipit.attachReport(document.getElementById("report-issue"));
</script>

<button onclick="Blipit.openReport()">Report Issue</button>
React
import { openReport } from "@blipit/browser";

export function ReportIssue() {
  return <button onClick={() => openReport()}>Report Issue</button>;
}
Vue
<script setup>
import { openReport } from "@blipit/browser";
</script>

<template>
  <button @click="openReport()">Report Issue</button>
</template>
网站页眉中的官方“报告问题”按钮。
网站页眉中的官方“报告问题”按钮。
页眉中的自定义 Report Issue 按钮会打开 Blipit 报告器。
页眉中的自定义 Report Issue 按钮会打开 Blipit 报告器。

9隐藏默认按钮

如果只想保留你自己的按钮,可以在代码中用 feedbackWidget: false 关闭浮动按钮(在 <Blipit /> 上使用 feedbackWidget={false}),或在项目的“错误报告小组件”设置中关闭“显示错误报告按钮”,从而在所有使用该密钥的网站上隐藏它。无论哪种方式,openReport() 和 attachReport() 都能继续使用。

js
Blipit.init({ key: import.meta.env.VITE_BLIPIT_KEY, feedbackWidget: false });

10预填报告器并添加上下文

在用户登录后调用 setUser:报告者的姓名和邮箱会自动填写,你回复或更改状态时对方会收到邮件。setReportMetadata 会把你自己的字段(例如套餐或购物车数量)添加到每份报告中;它在报告发送时运行,因此值始终是最新的。

js
Blipit.setUser({ id: "42", username: "Ana Lima", email: "ana@example.com" });

Blipit.setReportMetadata(() => ({ plan: "pro", cartItems: cart.length }));

11全部选项和函数

  • key:公钥(blipit_pk_)。必填。
  • environment 和 release:显示在每个事件上;release 用于回归检测和 source map。environment 默认为 production。
  • debug: true 会把 SDK 的操作记录到控制台,每行以 [blipit] 开头。
  • sampleRate(0 到 1)、ignoreErrors(字符串或正则)和 beforeSend(修改事件,或返回 null 以丢弃)控制发送的内容。autoMuteExtensions(默认开启)会丢弃仅来自浏览器扩展的错误。
  • webVitals(默认开启)、replay({ sessionSampleRate, onErrorSampleRate })和 autoSessionTracking(无崩溃率,需要 release)。
  • feedbackWidget: false 会隐藏“报告问题”按钮;传入包含 position、style、text、color 和 shortcut 的对象则可更改它。theme: "light"、"dark" 或 "auto" 设置报告器的主题。
  • user({ id, name, email })和 company(名称或 { id, name })会填入报告器并添加到报告中。
  • endpoint:仅用于自托管的接收服务;默认值为 https://in.blipit.io/api/v1/events。
  • 函数:captureException(error)、captureMessage(text, level)、setUser、setTag(key, value)、addBreadcrumb({ category, message })、openReport()、attachReport(element)、reportButton(options)、updateWidget(options)、setReportMetadata(fn)、showFeedback() 和 flush(),后者在排队的事件发送完成后返回一个 promise。
  • 在仪表板中更改的小组件设置最多一小时内会传到浏览器,因为 SDK 会缓存这么久;无痕窗口会立即显示更改。

12验证是否生效

重新加载你的网站。右下角会出现“报告问题”按钮,一分钟内页面浏览会显示在 app.blipit.io 的“Web 指标”下。然后发送一个测试事件:在代码中调用一次 captureMessage,或者在使用 script 标签时,在浏览器控制台中运行下面这一行。它会在几秒内出现在“问题”下。

js
Blipit.captureMessage("Hello from " + location.host, "info");

13如果按钮或事件没有出现

  • 打开浏览器控制台,查找以 [blipit] 开头的行。开启 debug(在 init 中设置 debug: true,或在 <Blipit /> 上设置 debug),即可查看按钮是已显示、在代码中被关闭,还是被项目设置隐藏。
  • Next.js 只会把名称以 NEXT_PUBLIC_ 开头的变量发送到浏览器,所以请使用 NEXT_PUBLIC_BLIPIT_KEY。Vite 只发送 VITE_ 变量,所以请使用 VITE_BLIPIT_KEY。使用其他任何名称,浏览器中的密钥都会为空,Blipit 也不会启动。
  • 添加或修改 .env 或 .env.local 后,请重启开发服务器。它只在启动时读取这些文件。
  • 在 Vercel 或其他任何托管平台上,在项目的环境变量中添加相同的变量,然后重新部署。NEXT_PUBLIC_ 和 VITE_ 的值会写入构建产物,因此正在运行的部署永远看不到之后添加的值。
  • 请使用公钥(blipit_pk_)。私密密钥(blipit_sk_)在浏览器中会被拒绝并在控制台报错;如果它曾出现在页面上,请创建新的私密密钥。
  • 在 Next.js 中,<Blipit /> 应放在根 app/layout.tsx(或 pages/_app.tsx)中,这样它会在每个页面运行。在其他应用中,在入口文件中、应用渲染之前调用一次 init。
  • 必须在 app.blipit.io 的“项目设置”›“错误报告小组件”中开启“显示错误报告按钮”,并且你的代码不能传入 feedbackWidget: false。SDK 会将项目设置缓存最多一小时,因此请在无痕窗口中测试更改。
  • 广告拦截器和隐私扩展可能会拦截 in.blipit.io。请在关闭扩展的无痕窗口中重试。
  • 如果你的网站发送 Content Security Policy,请允许 script-src https://blipit.io、connect-src https://in.blipit.io、img-src data: 和 media-src blob:。报告编辑器在第一次点击时从 blipit.io/sdk 加载,截图由一张 data: 图片绘制,屏幕录制也会上传到 in.blipit.io。开启 debug 后,控制台会提示策略何时阻止了截图。 要在屏幕录制中录入声音,网站的 Permissions-Policy 头必须允许 microphone=(self),屏幕录制还需要 display-capture=(self);设置为 microphone=() 时,录制没有声音。
  • 用 npm ls @blipit/browser @blipit/nextjs(或 pnpm list @blipit/browser @blipit/nextjs)查看已安装的版本,并与更新日志对比。pnpm 11 会在新版本发布一天后才安装它(minimum-release-age),所以在发布当天 pnpm add 会悄悄安装上一个版本。要立即获得新版本:pnpm add @blipit/browser@<version> @blipit/nextjs@<version> --config.minimum-release-age=0。
  • 仍未解决?请把控制台中的 [blipit] 行发邮件至 support@blipit.io。

打开完整的 任意网站 指南

2Next.js 和 React 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 npm install @blipit/nextjs

1安装

sh
npm install @blipit/nextjs

2获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

3把密钥放进 .env.local

在项目根目录创建 .env.local,写入供浏览器使用的公钥;如果你使用下面的服务端功能,还要写入供服务器使用的私密密钥。只有以 NEXT_PUBLIC_ 开头的名称会传到浏览器,所以切勿给私密密钥加这个前缀。保存文件后重启 npm run dev。对于生产环境,在你的托管平台中添加相同的变量(在 Vercel 上:Project、Settings、Environment Variables,勾选 Production 和 Preview),然后重新部署:NEXT_PUBLIC_ 的值会写入构建产物,因此在添加变量之前完成的部署中密钥为空。

.env.local
NEXT_PUBLIC_BLIPIT_KEY=blipit_pk_your_public_key
BLIPIT_SECRET_KEY=blipit_sk_your_secret_key

4浏览器端

在根布局中添加一次该组件。它从 NEXT_PUBLIC_BLIPIT_KEY 读取公钥。如果该变量为空,它不会启动任何功能,并会在浏览器控制台中说明。

app/layout.tsx
import { Blipit } from "@blipit/nextjs";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Blipit
          publicKey={process.env.NEXT_PUBLIC_BLIPIT_KEY!}
          environment={process.env.NEXT_PUBLIC_VERCEL_ENV ?? "development"}
          release={process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA}
          replay={{ onErrorSampleRate: 1 }}
        />
        {children}
      </body>
    </html>
  );
}

5服务端

Next.js 15 及更高版本会在 server component、route handler 和 server action 出错时调用 onRequestError。instrumentation.ts 中的一行代码即可将其接入 Blipit。从 @blipit/nextjs 0.2.1 起,同一行代码也适用于带有 middleware.ts 的应用和 Edge 路由(runtime = "edge"):应用可以正常构建,middleware 和 Edge 的错误也会上报。Next.js 14 没有 onRequestError,因此请像第二个示例那样用 withBlipit 包裹每个 route handler 和 server action:它会上报错误并重新抛出,并跳过重定向和 notFound()。在服务器环境中设置 BLIPIT_SECRET_KEY,切勿设为 NEXT_PUBLIC_。

instrumentation.ts
export { captureRequestError as onRequestError } from "@blipit/nextjs/server";
app/api/orders/route.ts
import { withBlipit } from "@blipit/nextjs/server";

export const GET = withBlipit(async (request: Request) => {
  return Response.json(await loadOrders());
});

6依赖服务和服务器健康

从 @blipit/nextjs 0.3 起,同时导出 register,让 Blipit 在服务器启动时开始运行。之后数据库和外部服务调用会显示在依赖服务页面,服务器的 CPU、内存和事件循环会显示在服务器健康页面。在 Edge 运行时中不做任何事。 在 Vercel 上,register 可能看不到传入请求:从 @blipit/nextjs 0.4 起,用 withBlipit 包装路由处理函数和 server action,每个都会成为 Pulse 页面上的一个请求,并附带其数据库和外部服务调用,在响应之后发送,不会拖慢响应。

instrumentation.ts
export { captureRequestError as onRequestError, register } from "@blipit/nextjs/server";
app/api/orders/route.ts
import { withBlipit } from "@blipit/nextjs/server";

export const GET = withBlipit(async (request: Request) => Response.json(await loadOrders()));

7由 error.tsx 捕获的错误

被 error.tsx 或 global-error.tsx 边界捕获的错误永远不会到达浏览器的错误处理程序,因此需要在边界中上报。这两个文件都是客户端组件。

app/error.tsx
"use client";

import { useEffect } from "react";
import { captureException } from "@blipit/nextjs";

export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
  useEffect(() => {
    captureException(error);
  }, [error]);
  return (
    <div>
      <p>Something went wrong.</p>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}
app/global-error.tsx
"use client";

import { useEffect } from "react";
import { captureException } from "@blipit/nextjs";

export default function GlobalError({ error }: { error: Error & { digest?: string } }) {
  useEffect(() => {
    captureException(error);
  }, [error]);
  return (
    <html>
      <body>
        <p>Something went wrong.</p>
      </body>
    </html>
  );
}

8不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

9Content Security Policy

如果你的网站发送 Content Security Policy,请允许 script-src https://blipit.io(script 标签,以及首次使用时从 blipit.io/sdk/<version>/ 加载的报告编辑器和回放插件)、connect-src https://in.blipit.io(事件、截图和屏幕录制都发送到 in.blipit.io)、img-src data:(截图由页面的一张图片绘制而成)和 media-src blob:(录制内容在报告窗口中播放)。截图会重新加载页面的图片和字体,因此它们的主机也要加入 connect-src,否则会显示为空白。无需修改 style-src。使用 script 标签时,请从你自己的 .js 文件中调用 Blipit.init,或为内联脚本设置 nonce,因为严格的策略会阻止内联脚本。 要在屏幕录制中录入声音,网站的 Permissions-Policy 头必须允许 microphone=(self),屏幕录制还需要 display-capture=(self);设置为 microphone=() 时,录制没有声音。

10Source map(可选)

为了让堆栈跟踪显示你的源码而不是压缩后的 bundle,请在构建步骤中为每个 release 上传 map 文件。

sh
BLIPIT_KEY=<secret key> npx @blipit/cli sourcemaps upload .next/static --release "$VERCEL_GIT_COMMIT_SHA"

11错误报告:“报告问题”按钮

SDK 使用你的公钥启动后,每个页面的右下角就会出现一个“报告问题”按钮,使用访客的语言。点击后会打开报告器:一张可标注的页面截图、一个元素选择器、可选的屏幕录制,以及标题和描述。你可以像下面这样在代码中更改位置、样式、文字、颜色和快捷键,也可以在 app.blipit.io 的“项目设置”›“错误报告小组件”中一次性为所有网站更改;代码中的选项优先。“错误报告按钮”指南用截图和在线演示展示了每个选项。

app/layout.tsx
<Blipit
  publicKey={process.env.NEXT_PUBLIC_BLIPIT_KEY!}
  feedbackWidget={{
    position: "bottom-left",
    style: "icon",
    text: "Report Issue",
    color: "#E11D48",
    shortcut: "ctrl+shift+b",
  }}
/>
默认的“报告问题”按钮,位于右下角。
默认的“报告问题”按钮,位于右下角。
报告器:已标注的截图、标题和问题描述。
报告器:已标注的截图、标题和问题描述。

12从你自己的按钮打开报告器

用 <BlipitReportButton /> 把官方按钮放在任何位置,服务器组件中也可以:它显示 Blipit 图标和访客语言的“报告问题”,并打开报告窗口。想用自己的设计?调用 openReport 的组件必须是客户端组件,所以要在文件顶部加上 "use client"。<Blipit /> 必须已经放在 app/layout.tsx 中。不使用 Next.js 的 React 应用从 @blipit/nextjs/react 导入按钮,从 @blipit/browser 导入 openReport。

app/header.tsx
import { BlipitReportButton } from "@blipit/nextjs";

export function Header() {
  return (
    <header>
      <a href="/">Acme</a>
      <BlipitReportButton />
    </header>
  );
}
不使用 Next.js 的 React
import { BlipitReportButton } from "@blipit/nextjs/react";

<BlipitReportButton variant="outline" size="sm" />
app/report-issue.tsx
"use client";

import { openReport } from "@blipit/nextjs";

export function ReportIssue() {
  return <button onClick={() => openReport()}>Report Issue</button>;
}
React(@blipit/browser)
import { openReport } from "@blipit/browser";

export function ReportIssue() {
  return <button onClick={() => openReport()}>Report Issue</button>;
}
网站页眉中的官方“报告问题”按钮。
网站页眉中的官方“报告问题”按钮。
一个 Next.js 应用:页眉中的自定义 Report Issue 按钮打开了 Blipit 报告器。
一个 Next.js 应用:页眉中的自定义 Report Issue 按钮打开了 Blipit 报告器。

13隐藏默认按钮

如果只想保留你自己的按钮,可以在代码中用 feedbackWidget: false 关闭浮动按钮(在 <Blipit /> 上使用 feedbackWidget={false}),或在项目的“错误报告小组件”设置中关闭“显示错误报告按钮”,从而在所有使用该密钥的网站上隐藏它。无论哪种方式,openReport() 和 attachReport() 都能继续使用。

app/layout.tsx
<Blipit publicKey={process.env.NEXT_PUBLIC_BLIPIT_KEY!} feedbackWidget={false} />

14预填报告器并添加上下文

在用户登录后调用 setUser:报告者的姓名和邮箱会自动填写,你回复或更改状态时对方会收到邮件。setReportMetadata 会把你自己的字段(例如套餐或购物车数量)添加到每份报告中;它在报告发送时运行,因此值始终是最新的。

app/blipit-user.tsx
"use client";

import { useEffect } from "react";
import { setReportMetadata, setUser } from "@blipit/nextjs";

export function BlipitUser({ user }: { user: { id: string; name: string; email: string; plan: string } }) {
  useEffect(() => {
    setUser({ id: user.id, username: user.name, email: user.email });
    setReportMetadata(() => ({ plan: user.plan }));
  }, [user]);
  return null;
}

15验证是否生效

重新加载应用。右下角会出现“报告问题”按钮,一分钟内页面浏览会显示在 app.blipit.io 的“Web 指标”下。然后添加一个调用 captureMessage 的按钮,或一个会抛出错误的按钮,并点击它:事件会在几秒内出现在“问题”下。

tsx
"use client";
import { captureMessage } from "@blipit/nextjs";

export function TestBlipit() {
  return <button onClick={() => captureMessage("Hello from Next.js")}>Send a test event</button>;
}

16如果按钮或事件没有出现

  • 打开浏览器控制台,查找以 [blipit] 开头的行。开启 debug(在 init 中设置 debug: true,或在 <Blipit /> 上设置 debug),即可查看按钮是已显示、在代码中被关闭,还是被项目设置隐藏。
  • Next.js 只会把名称以 NEXT_PUBLIC_ 开头的变量发送到浏览器,所以请使用 NEXT_PUBLIC_BLIPIT_KEY。Vite 只发送 VITE_ 变量,所以请使用 VITE_BLIPIT_KEY。使用其他任何名称,浏览器中的密钥都会为空,Blipit 也不会启动。
  • 添加或修改 .env 或 .env.local 后,请重启开发服务器。它只在启动时读取这些文件。
  • 在 Vercel 或其他任何托管平台上,在项目的环境变量中添加相同的变量,然后重新部署。NEXT_PUBLIC_ 和 VITE_ 的值会写入构建产物,因此正在运行的部署永远看不到之后添加的值。
  • 请使用公钥(blipit_pk_)。私密密钥(blipit_sk_)在浏览器中会被拒绝并在控制台报错;如果它曾出现在页面上,请创建新的私密密钥。
  • 在 Next.js 中,<Blipit /> 应放在根 app/layout.tsx(或 pages/_app.tsx)中,这样它会在每个页面运行。在其他应用中,在入口文件中、应用渲染之前调用一次 init。
  • 必须在 app.blipit.io 的“项目设置”›“错误报告小组件”中开启“显示错误报告按钮”,并且你的代码不能传入 feedbackWidget: false。SDK 会将项目设置缓存最多一小时,因此请在无痕窗口中测试更改。
  • 广告拦截器和隐私扩展可能会拦截 in.blipit.io。请在关闭扩展的无痕窗口中重试。
  • 如果你的网站发送 Content Security Policy,请允许 script-src https://blipit.io、connect-src https://in.blipit.io、img-src data: 和 media-src blob:。报告编辑器在第一次点击时从 blipit.io/sdk 加载,截图由一张 data: 图片绘制,屏幕录制也会上传到 in.blipit.io。开启 debug 后,控制台会提示策略何时阻止了截图。 要在屏幕录制中录入声音,网站的 Permissions-Policy 头必须允许 microphone=(self),屏幕录制还需要 display-capture=(self);设置为 microphone=() 时,录制没有声音。
  • 用 npm ls @blipit/browser @blipit/nextjs(或 pnpm list @blipit/browser @blipit/nextjs)查看已安装的版本,并与更新日志对比。pnpm 11 会在新版本发布一天后才安装它(minimum-release-age),所以在发布当天 pnpm add 会悄悄安装上一个版本。要立即获得新版本:pnpm add @blipit/browser@<version> @blipit/nextjs@<version> --config.minimum-release-age=0。
  • 仍未解决?请把控制台中的 [blipit] 行发邮件至 support@blipit.io。

打开完整的 Next.js 和 React 指南

2Node.js 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 npm install @blipit/node

1安装

sh
npm install @blipit/node

2获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

3将密钥保存在环境变量中

Node 使用私密密钥。请把它放在环境变量中,切勿写进代码:本地放在 .env 文件中(Node 20.6 及以上版本可用 --env-file 加载),生产环境放在托管平台的环境变量或密钥设置中(Fly secrets、Docker、systemd、Render、Vercel)。修改后请重启进程。

.env
BLIPIT_SECRET_KEY=blipit_sk_your_secret_key
sh
node --env-file=.env --import ./instrument.mjs server.mjs

4不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

5先初始化

把这段代码放在一个在你的应用之前运行的文件中,并最先导入它。

instrument.mjs
import * as Blipit from "@blipit/node";

Blipit.init({
  key: process.env.BLIPIT_SECRET_KEY,
  environment: process.env.NODE_ENV,
  release: process.env.RELEASE,
  serverName: "api",
});

6Express、Fastify、Koa、Hono 或 NestJS

在路由之后添加 handler,这样已处理和未处理的错误都会到达 Blipit,并附带请求的方法、URL 和 user agent。 Koa、Hono 和 NestJS 各只需一行:Koa 的中间件放在最前面,Hono 的放在路由之前。它们上报状态码为 500 及以上的错误。之后请求在 Pulse 页面按路由显示,例如 GET /users/:id,而不是每个 URL 一行。

js
import "./instrument.mjs";
import * as Blipit from "@blipit/node";
import express from "express";

const app = express();
app.get("/", (req, res) => res.send("ok"));
app.use(Blipit.expressErrorHandler());
app.listen(3000);
Fastify
await app.register(Blipit.fastifyPlugin());
Koa
app.use(Blipit.koaMiddleware());
Hono
app.use(Blipit.honoMiddleware());
NestJS
app.useGlobalInterceptors(Blipit.nestInterceptor());

7无服务器:AWS Lambda 和 Vercel

无服务器平台在函数一返回响应就会暂停它,而且 Lambda 不运行 Node 的 HTTP 服务器,所以请包装处理函数。wrapHandler 会记录请求(API Gateway、函数 URL 和负载均衡器事件按方法和路由命名,其他事件按函数名),上报错误,并在处理函数返回前发送所有数据;只有在有数据要发送时才会等待,最多 2 秒。traceRequest 对任何接收 Request 的处理函数做同样的事。在 Vercel 上,数据在响应之后通过 waitUntil 发送,不会造成任何延迟。在 Next.js 中请使用 withBlipit(见 Next.js 指南)。

js
import * as Blipit from "@blipit/node";

export const handler = Blipit.wrapHandler(async (event, context) => {
  return { statusCode: 200, body: "ok" };
});
traceRequest
export default { fetch: (request) => Blipit.traceRequest(request, () => app.fetch(request)) };

8手动捕获、日志和登录尝试

js
Blipit.captureException(err);
Blipit.captureMessage("cache miss rate above 50%", "warning");
Blipit.setUser({ id: "user-42" });
Blipit.log.info("order placed", { order_id: 42 });
Blipit.captureSecurity({ kind: "login_failed", actor: email, ip, userAgent, outcome: "bad_password" });
await Blipit.flush();

9依赖服务和服务器健康

从 0.2 起,SDK 还会记录你的数据库和外部服务调用,以及服务器的 CPU、内存和事件循环。请参阅依赖服务和服务器健康指南;可用 tracesSampleRate、tracing: false 和 metrics: false 控制。

10验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

js
Blipit.captureMessage("Hello from Node");

打开完整的 Node.js 指南

2Python 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 pip install blipit

1安装

sh
pip install blipit

2启动时初始化

Django 放在 settings.py 顶部;Flask 或 FastAPI 放在创建应用之前。密钥在项目的“密钥”页面上。密钥为空时,init 会记录一条警告并返回 False,而不会抛出异常,因此缺少密钥绝不会阻止应用启动。

python
import blipit

blipit.init(
    key="<public key>",
    environment="production",
    release="myapp@1.4.2",
)

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在环境变量中

此 SDK 使用项目“API 密钥”页面上的公钥发送数据。请把它放在环境变量中:本地放在由框架或 python-dotenv 加载的 .env 文件里,生产环境放在托管平台的设置中。只有发送登录尝试时才需要私密密钥。

.env
BLIPIT_KEY=blipit_pk_your_public_key
python
import os
import blipit

blipit.init(key=os.environ.get("BLIPIT_KEY"))

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

python
blipit.capture_exception(err)
blipit.capture_message("cache miss rate above 50%", level="warning")
blipit.set_user({"id": "42", "email": "ana@example.com"})
blipit.set_context("order", {"id": 1042, "total": 99.5})
blipit.capture_security("login_failed", actor=email, ip=request.META.get("REMOTE_ADDR"), outcome="bad_password")

7验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

python
blipit.capture_message("Hello from Python")

打开完整的 Python 指南

2PHP 和 Laravel 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 composer require blipit/blipit

1安装

sh
composer require blipit/blipit

2启动时初始化

纯 PHP:放在前端控制器顶部,在处理任何请求之前。Laravel 会从其配置启动 Blipit,见下一步。密钥在项目的“密钥”页面上。密钥为空时,init 会向错误日志写入一条警告并返回 false,而不会抛出异常。

php
use Blipit\Blipit;

Blipit::init([
    "key" => "<public key>",
    "environment" => "production",
    "release" => "myapp@1.4.2",
]);

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在环境变量中

此 SDK 使用公钥发送数据。Laravel:把它加入 .env 和 config/services.php;Blipit 服务提供者会被自动发现,并从该配置启动 Blipit,无需其他操作。请通过 config 读取这些值,因为配置被缓存后,env() 在应用代码中不会返回任何内容。纯 PHP:用 getenv() 从服务器环境中读取密钥。

.env
BLIPIT_KEY=blipit_pk_your_public_key
config/services.php
'blipit' => [
    'key' => env('BLIPIT_KEY'),
    'environment' => env('APP_ENV'),
    'release' => env('GIT_SHA'),
],

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6Laravel 和 Symfony

Laravel:其异常处理器上报的每个异常都会到达 Blipit,因此 404 和验证错误不会被发送。查询、日志行和 HTTP 客户端调用会变成面包屑,队列任务会被追踪。bootstrap/app.php 中已有的 Blipit::captureException 行可以保留:同一个异常绝不会发送两次。Symfony:在 config/services.yaml 中注册监听器,并在 public/index.php 和 bin/console 中尽早调用 Blipit::init。

config/services.yaml
Blipit\Symfony\BlipitListener:
    arguments: ['@router']
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        - { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate }
        - { name: kernel.event_listener, event: console.error, method: onConsoleError }

7手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

php
Blipit::captureException($e);
Blipit::captureMessage("cache miss rate above 50%", "warning");
Blipit::setUser(["id" => "42", "email" => "ana@example.com"]);
Blipit::captureSecurity("login_failed", $email, "bad_password", null, $request->ip(), $request->userAgent());

8验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

php
Blipit::captureMessage("Hello from PHP");

打开完整的 PHP 和 Laravel 指南

2Ruby 和 Rails 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 gem install blipit

1Gemfile

ruby
gem "blipit"

2启动时初始化

Rails:放在 config/initializers/blipit.rb;无需再安装其他东西,因为 Blipit 会自动添加其 Rack 中间件、Active Job 和 Rails.error 上报。Rack 和 Sinatra 应用添加 use Blipit::Rack。脚本:放在代码运行之前。密钥在项目的“密钥”页面上。密钥为空时,init 会打印一条警告并返回 false,而不会抛出异常。

ruby
Blipit.init(
  key: "<public key>",
  environment: Rails.env,
  release: ENV["RELEASE"],
)

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在 Rails credentials 中

此 SDK 使用公钥发送数据。在 Rails 中,把它放在加密的 credentials 里并在 initializer 中读取;其他场景使用环境变量。

sh
bin/rails credentials:edit
credentials
blipit:
  key: blipit_pk_your_public_key
config/initializers/blipit.rb
Blipit.init(
  key: Rails.application.credentials.dig(:blipit, :key),
  environment: Rails.env,
)

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

ruby
Blipit.capture_exception(e)
Blipit.capture_message("cache miss rate above 50%", level: :warning)
Blipit.set_user(id: "42", email: "ana@example.com")
Blipit.capture_security("login_failed", email, outcome: "bad_password", ip: request.remote_ip, user_agent: request.user_agent)

7验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

ruby
Blipit.capture_message("Hello from Rails")

打开完整的 Ruby 和 Rails 指南

2Go 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 go get github.com/blipit-io/blipit-go

1安装

sh
go get github.com/blipit-io/blipit-go

2在 main 中初始化

Init 绝不会 panic:密钥或项目 id 为空时,它会返回错误并保持 Blipit 关闭,因此请记录该错误,而不是退出程序。

go
import (
    "log"
    "time"

    "github.com/blipit-io/blipit-go"
)

func main() {
    if err := blipit.Init(blipit.Options{
        Key:         "<public key>",
        Project:     "<project id>",
        Environment: "production",
        Release:     "myapp@1.4.2",
    }); err != nil {
        log.Printf("blipit: %v", err)
    }
    defer blipit.Flush(2 * time.Second)
}

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在环境变量中

此 SDK 使用公钥和项目 id 发送数据。从托管平台、systemd unit 或 docker run -e 设置的环境变量中读取它们。

go
blipit.Init(blipit.Options{
    Key:     os.Getenv("BLIPIT_KEY"),
    Project: os.Getenv("BLIPIT_PROJECT"),
})

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

go
blipit.CaptureException(err)
blipit.CaptureMessage("cache miss rate above 50%")
blipit.SetUser(blipit.User{ID: "42", Email: "ana@example.com"})
blipit.CaptureSecurity(blipit.Security{Kind: "login_failed", Actor: email, IP: ip, UserAgent: agent, Outcome: "bad_password"})

7Panic 和 net/http

在 main 或任意 goroutine 顶部写上 defer blipit.Recover(),即可上报带堆栈的 panic,刷新队列后再次 panic。用 blipit.Handler 包装你提供服务的 handler,即可上报带请求信息的 panic,并在 Pulse 上为每个请求计时,以其 ServeMux 模式命名。Gin、Echo 和 Fiber 使用 StartRequest、SetRoute 和 End,见包的 README。

go
go func() {
    defer blipit.Recover()
    work()
}()

mux := http.NewServeMux()
mux.HandleFunc("GET /items/{id}", item)
http.ListenAndServe(":8080", blipit.Handler(mux))

8验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

go
blipit.CaptureMessage("Hello from Go")

打开完整的 Go 指南

2Java 和 Kotlin 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 com.github.blipit-io:blipit-java

1添加仓库和依赖

build.gradle.kts
repositories {
    mavenCentral()
    maven("https://jitpack.io")
}

dependencies {
    implementation("com.github.blipit-io:blipit-java:v0.2.1")
}
pom.xml
<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

<dependency>
  <groupId>com.github.blipit-io</groupId>
  <artifactId>blipit-java</artifactId>
  <version>v0.2.1</version>
</dependency>

2启动时初始化

Spring Boot:放在 main 顶部、SpringApplication.run 之前,或放在 @Configuration 类的 @PostConstruct 方法中。任何线程上的未捕获异常都会在应用停止前写入磁盘队列,然后发送,因此即使网络断开,崩溃也能上报;剩下未发出的会在下次启动时发送。

java
import io.blipit.Blipit;
import io.blipit.BlipitOptions;

Blipit.init(BlipitOptions.builder()
    .key("<public key>")
    .project(<project id>)
    .environment("production")
    .release("myapp@1.4.2")
    .build());

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在环境变量中

此 SDK 使用公钥和项目 id 发送数据。从环境变量中读取它们;在 Spring Boot 中,可从由环境变量填充的 application.properties 中读取。

application.properties
blipit.key=${BLIPIT_KEY}
blipit.project=${BLIPIT_PROJECT}
java
Blipit.init(BlipitOptions.builder()
    .key(System.getenv("BLIPIT_KEY"))
    .project(Long.parseLong(System.getenv("BLIPIT_PROJECT")))
    .build());

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

java
Blipit.captureException(err);
Blipit.captureMessage("cache miss rate above 50%");
Blipit.captureMessage("disk almost full", Level.WARNING);
Blipit.setUser("42", "ana@example.com");
Blipit.addBreadcrumb("GET /api/cart 500", "http", Level.ERROR);
Blipit.captureSecurity("login_failed", email, "bad_password", null, ip, userAgent, null);

7验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

java
Blipit.captureMessage("Hello from Java");

打开完整的 Java 和 Kotlin 指南

2.NET 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 dotnet add package Blipit

1安装

sh
dotnet add package Blipit

2启动时初始化

在进程的整个生命周期内保持返回的句柄存活。两个值都在项目的密钥页面上。

Program.cs
using Blipit;

using var blipit = Blipit.Blipit.Init(new BlipitOptions
{
    Key = "<public key>",
    Project = "<project id>",
    Environment = "production",
    Release = "myapp@1.4.2",
});

3获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

4将密钥保存在配置中

此 SDK 使用公钥和项目 id 发送数据。开发时把它们保存在 user secrets 中,生产环境放在环境变量中(Blipit__Key 和 Blipit__Project),然后从配置中读取。

sh
dotnet user-secrets set "Blipit:Key" "blipit_pk_your_public_key"
dotnet user-secrets set "Blipit:Project" "12"
Program.cs
using var blipit = Blipit.Blipit.Init(new BlipitOptions
{
    Key = builder.Configuration["Blipit:Key"],
    Project = builder.Configuration["Blipit:Project"],
});

5不要把密钥放进 git

请把密钥保存在环境变量或托管平台的密钥设置中,切勿写进你提交的代码,并把 .env 文件加入 .gitignore。网页中出现公钥是正常的。如果私密密钥曾出现在 git、公开页面、截图或聊天中,请打开“API 密钥”,点击“创建新的密钥”,并在所有用过旧密钥的地方粘贴新密钥:旧密钥会立即失效。

.gitignore
.env
.env.local
.env.*.local

6ASP.NET Core 与日志

无需添加其他内容:在 Program.cs 顶部调用 Init 即可。来自端点、控制器和中间件的异常会连同请求一起上报,即使由 UseExceptionHandler 处理也一样;设置 TracesSampleRate 后,每个被采样的请求都会按路由在 Pulse 上计时。BlipitLoggerProvider 会把 Information 及以上级别变为面包屑,Error 及以上级别变为事件。

Program.cs
var builder = WebApplication.CreateBuilder(args);
using var blipit = Blipit.Blipit.Init(new BlipitOptions
{
    Key = builder.Configuration["Blipit:Key"],
    Project = builder.Configuration["Blipit:Project"],
    TracesSampleRate = 0.2,
});
builder.Logging.AddProvider(new BlipitLoggerProvider());

7手动捕获和登录尝试

登录尝试需要私密密钥:请在服务器上使用私密密钥而不是公开密钥进行初始化,否则接收端会以 403 security_needs_secret_key 拒绝。Scale 套餐。

csharp
Blipit.Blipit.CaptureException(ex);
Blipit.Blipit.CaptureMessage("cache miss rate above 50%", BlipitLevel.Warning);
Blipit.Blipit.SetUser(id: "42", email: "ana@example.com");
Blipit.Blipit.CaptureSecurity("login_failed", email, "bad_password", null, ip, userAgent, null);

8验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

csharp
Blipit.Blipit.CaptureMessage("Hello from .NET");

打开完整的 .NET 指南

2iOS、Android、Flutter、React Native 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 one package per platform

1获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

2React Native

该包会链接一个小型原生模块,用于启动 Blipit 自己的 Android 和 iOS SDK 以捕获原生崩溃;其 Gradle 文件会自动添加 JitPack 仓库。包装根组件,渲染错误也会被上报。

sh
npm install @blipit/react-native
npx pod-install
tsx
import * as Blipit from "@blipit/react-native";

Blipit.init({ key: "<public key>", project: <project id>, environment: "production", release: "myapp@1.4.2" });

export default Blipit.wrap(App);

3Flutter

把 main.dart 中的 runApp 替换为 Blipit.init。插件会启动 Blipit 自己的 Android 和 iOS SDK 以捕获原生崩溃,Flutter 框架错误和未捕获的异步错误会自动上报。

sh
flutter pub add blipit_flutter
main.dart
import 'package:blipit_flutter/blipit_flutter.dart';

Future<void> main() async {
  await Blipit.init(
    key: '<public key>',
    project: <project id>,
    environment: 'production',
    release: 'myapp@1.4.2',
    appRunner: () => runApp(const MyApp()),
  );
}

4iOS 和 macOS(Swift Package)

在 Xcode 中选择 File、Add Package Dependencies,输入仓库 URL;或者把它加入 Package.swift,并将 BlipitSwift 添加到你的 target。使用 CocoaPods 时,请用 BlipitSwift pod。然后在启动时调用一次 start。密钥或项目 id 为空时,start 会打印一条警告并返回 false,而不会让应用崩溃。

Package.swift
.package(url: "https://github.com/blipit-io/blipit-swift", from: "0.6.0")
Podfile
pod "BlipitSwift", "~> 0.6.0"
swift
import BlipitSwift

Blipit.start(key: "<public key>", project: "<project id>", environment: "production", release: "myapp@1.4.2")

5Android

在 settings.gradle.kts 的 repositories 中添加 JitPack,在 app 模块中添加依赖,并在 Application.onCreate 中调用 init。

settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://jitpack.io")
    }
}
build.gradle.kts (app)
implementation("com.github.blipit-io:blipit-android:v0.6.0")
kotlin
import io.blipit.android.Blipit

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Blipit.init(this) {
            key = "<public key>"
            project = "<project id>"
            environment = "production"
            release = "myapp@1.4.2"
        }
    }
}

6应用中的密钥放在哪里

应用会把公钥和项目 id 打包在应用内,这没有问题:公钥只能发送事件。切勿把私密密钥放进应用。请在构建时传入它们,避免进入你的代码仓库。

Flutter
flutter run --dart-define=BLIPIT_KEY=blipit_pk_your_public_key --dart-define=BLIPIT_PROJECT=12
main.dart
const key = String.fromEnvironment('BLIPIT_KEY');
const project = int.fromEnvironment('BLIPIT_PROJECT');
Expo(.env)
EXPO_PUBLIC_BLIPIT_KEY=blipit_pk_your_public_key
EXPO_PUBLIC_BLIPIT_PROJECT=12
Android build.gradle.kts
buildConfigField("String", "BLIPIT_KEY", ""${project.findProperty("blipitKey")}"")
iOS xcconfig
BLIPIT_KEY = blipit_pk_your_public_key

7应用中的错误报告

从你自己的菜单项调用 showReport,或开启悬浮的“报告问题”按钮。报告工具会先询问如何展示问题:截屏、录屏(iOS)或只描述。截图以全屏打开,工具栏位于图片上方和下方,从不遮挡图片;双指捏合或双击即可缩放,标出问题,再填写标题和发生了什么后发送。报告会连同设备信息出现在“错误报告”中。React Native 截图需要 react-native-view-shot。

React Native
import * as Blipit from "@blipit/react-native";

export default function Root() {
  return (
    <Blipit.BlipitReporter showButton>
      <App />
    </Blipit.BlipitReporter>
  );
}

Blipit.showReport();
Flutter
appRunner: () => runApp(const BlipitReporter(showButton: true, child: MyApp())),

Blipit.showReport();
iOS
Blipit.showReportButton()

Blipit.showReport()
Android
Blipit.showReportButton()

Blipit.showReport()

8在出问题的屏幕上报告

放在“个人资料”等菜单里的“报告问题”截到的是菜单,而不是问题。请开启从当前屏幕直接发起的方式;它们默认都关闭,也不会请求任何权限。shakeToReport 在摇动手机时打开报告页面。screenshotToReport 在普通截屏后询问“要用此屏幕报告问题吗?”,并附上 Blipit 自己的截图(iOS 以及 Android 14 及以上)。twoFingerReport 在双指按住约一秒后打开,不会妨碍应用自身的触摸。reportAfterCrash 在崩溃后的第一次启动时询问用户当时在做什么,并把报告关联到该崩溃。默认开启的 screenPicker 让从菜单打开报告的人选择问题出现在最近的哪个屏幕:快照只保存在设备内存中,只上传选中的那一张。Jetpack Compose 和 SwiftUI 应用用 setScreen 为屏幕命名。

Android
Blipit.init(this) {
    key = "<public key>"
    project = "<project id>"
    shakeToReport = true
    screenshotToReport = true
    twoFingerReport = true
    reportAfterCrash = true
}

navController.addOnDestinationChangedListener { _, destination, _ ->
    Blipit.setScreen(destination.route ?: "screen")
}
iOS
Blipit.start(key: "<public key>", project: "<project id>") { options in
    options.shakeToReport = true
    options.screenshotToReport = true
    options.twoFingerReport = true
    options.reportAfterCrash = true
}

CartView().onAppear { Blipit.setScreen("Cart") }
React Native
Blipit.init({
  key: "<public key>",
  project: <project id>,
  shakeToReport: true,
  screenshotToReport: true,
  twoFingerReport: true,
  reportAfterCrash: true,
});

<NavigationContainer ref={navigation} onReady={() => Blipit.trackNavigation(navigation)}>
Flutter
await Blipit.init(
  key: '<public key>',
  project: <project id>,
  shakeToReport: true,
  screenshotToReport: true,
  twoFingerReport: true,
  reportAfterCrash: true,
  appRunner: () => runApp(BlipitReporter(child: MaterialApp(navigatorObservers: [BlipitNavigatorObserver()], home: const Home()))),
);

9仅对测试人员显示的悬浮按钮

在 app.blipit.io 打开项目,在问题报告按钮设置中把“手机应用中的悬浮按钮”设为“所有人”或“仅测试人员”,每位测试人员填写一个用户 ID 或邮箱。应用会发送通过 setUser 设置的用户,Blipit 只回答是或否,因此测试人员名单永远不会打包进应用。调用 showReportButton(React Native 和 Flutter 中为 showButton)仍会对所有人显示按钮。

Android
Blipit.setUser(id = user.id, email = user.email)
iOS
Blipit.setUser(id: user.id, email: user.email)
React Native
Blipit.setUser({ id: user.id, email: user.email });
Flutter
Blipit.setUser(BlipitUser(id: user.id, email: user.email));

10发现卡住的应用

有些故障从不崩溃:启动画面一直转圈,或登录一直没有返回。打开 waitForReady,并在第一个可用界面出现时调用 reportReady。用 startFlow 和 endFlow 包住登录等流程,并用 flowStep 标记步骤。如果某个流程没有按时完成,Blipit 会创建一个“卡住”问题,附上最后一步和之前的轨迹。只计算显示在屏幕上的时间,时间上限由 Blipit 设定。名称会按原样发送,请使用固定名称,绝不要使用邮箱或其他用户数据。

Android
Blipit.init(this) {
    key = "<public key>"
    project = "<project id>"
    waitForReady = true
}

Blipit.reportReady()

Blipit.startFlow("sign-in")
Blipit.flowStep("sign-in", "google-picker")
Blipit.endFlow("sign-in")
iOS
Blipit.start(key: "<public key>", project: "<project id>", waitForReady: true)

Blipit.reportReady()

Blipit.startFlow("sign-in")
Blipit.flowStep("sign-in", "apple-sheet")
Blipit.endFlow("sign-in")
React Native
Blipit.init({ key: "<public key>", project: <project id>, waitForReady: true });

Blipit.reportReady();

Blipit.startFlow("sign-in");
Blipit.flowStep("sign-in", "google-picker");
Blipit.endFlow("sign-in");
Flutter
await Blipit.init(key: '<public key>', project: <project id>, waitForReady: true, appRunner: () => runApp(const MyApp()));

Blipit.reportReady();

Blipit.startFlow('sign-in');
Blipit.flowStep('sign-in', 'google-picker');
Blipit.endFlow('sign-in');

11验证是否生效

打开 app.blipit.io 中的“问题”。首个事件几秒钟内就会出现,并归组为一个问题,负责人会收到邮件。

打开完整的 iOS、Android、Flutter、React Native 指南

2Odoo 的步骤

已登录 Blipit?打开密钥页面,即可看到已填好项目密钥、可直接复制的这些步骤。

显示我的密钥

安装 Blipit Error Monitoring on the Odoo Apps store

1安装模块

从 apps.odoo.com 下载对应你 Odoo 版本的模块(blipit_monitor,免费),像安装其他模块一样安装:应用 › 更新应用列表 › 安装 Blipit Error Monitoring。Odoo Online 不允许第三方应用;Odoo.sh 和本地部署可以。

2获取密钥

登录 app.blipit.io,打开侧边栏中的“API 密钥”,然后选择你的项目。每个项目有两个密钥。公钥以 blipit_pk_ 开头:它用于浏览器和应用代码,只能发送事件,任何人看到都没关系。私密密钥以 blipit_sk_ 开头:它留在你的服务器或 Odoo 中,切勿放进浏览器,因为它还可以读取和更改问题。私密密钥只在创建后显示一次,请当时就复制;如果丢失,请点击“创建新的密钥”,旧密钥会立即失效。部分 SDK 还需要项目 id,它显示在同一页面上。

app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
app.blipit.io 中的 API 密钥:公钥(blipit_pk_)用于浏览器代码,私密密钥(blipit_sk_)用于服务器和 Odoo。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。
新的私密密钥只显示一次。请立即复制:它以哈希形式存储,无法再次显示。

3连接

设置 › Blipit:粘贴项目的私密密钥,勾选同意条款和模块许可证,然后点击“保存”。它会自动连接并显示“已连接到 <project>”。公钥或已绑定到其他数据库的密钥会被拒绝并说明原因。

4负责人

选择谁会收到邮件;如果有多家公司,可按公司选择。每个人占用套餐的一个席位;保存时 Blipit 会检查数量。

5来自 Odoo 的错误报告

该模块会自动把“报告问题”按钮添加到 Odoo 中,无需编写代码。在“设置”›“Blipit”›“错误报告”›“显示给”中选择谁能看到它:“内部用户”“网站访客”“两者”或“无人”,还可以把内部用户限制为某一个群组。报告会带上用户当时所在的模型、记录和字段,并自动填写已登录用户的姓名和邮箱。位置、颜色、文字和样式来自 app.blipit.io 的“项目设置”›“错误报告小组件”。每个选项请参见“错误报告按钮”指南。

6验证是否生效

在 Odoo 中打开 Blipit 应用。下一个错误会出现在那里以及负责人的收件箱中。点击“从 Blipit 刷新”可立即检查。

打开完整的 Odoo 指南