关于 dt-obs-android
为编码 Agent 提供 Android 项目 Dynatrace 基础埋点指导,从环境预检到构建验证。它按项目的 Gradle DSL 和入口文件类型修改配置,并在执行失败时要求回滚更改。
主要功能
- 01检查 Android 项目及工具版本
- 02识别已有 Dynatrace 配置并收集参数
- 03按 Gradle DSL 配置插件和应用信息
- 04在入口文件添加隐私同意调用
- 05构建验证并在失败时回滚
适用场景
- 01为 Android 应用添加 Dynatrace 基础监控
- 02更新已有 Dynatrace 埋点设置
- 03在修改失败后恢复项目文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dynatrace/ dynatrace-for-ai --skill dt-obs-android安装后在 Claude Code 中输入/dt-obs-android确认已加载。
详细介绍
Android Dynatrace 插桩
**范围:**仅限基本设置——从零开始,直到收到第一个事件。如需了解初始插桩之外的内容(自定义操作、崩溃分组、数据隐私政策等),请直接参阅 Dynatrace 文档。
阶段 1:预检
在进行任何操作之前,先检查当前目录是否为 Android 项目根目录:查找 settings.gradle.kts 或 settings.gradle。如果两者都不存在,请停止并告知用户当前目录不是 Android 项目根目录,并请他们切换到正确的目录。
然后验证以下最低要求。如果任何一项不满足,请停止并告知用户需要升级哪些内容,再继续操作:
| 要求 | 最低版本 |
|---|---|
| Gradle | 7.0.2 |
| Android Gradle Plugin(AGP) | 7.0 |
| JVM | Java 11 |
运行 ./gradlew --version(Windows 上运行 gradlew.bat --version)。输出同时包含 Gradle 版本和 Gradle 实际使用的 JVM(Daemon JVM 行);当项目在 Android Studio 或 IntelliJ 中打开时,该 JVM 可能与系统 Java 不同。不要使用 java -version——它报告的 JDK 可能与实际运行构建的 JDK 不同。AGP 版本在根构建文件中声明。
阶段 2:检测现有设置
如果在任何构建文件中找到 dynatrace { } 块,或 configure<com.dynatrace.tools.android.dsl.DynatraceExtension> { } 块(导入该类时也可写作 configure<DynatraceExtension> { }),请读取该块,并在存在时提取以下内容:
applicationId(传递给applicationId(...)或applicationId '...'的值)beaconUrl(传递给beaconUrl(...)或beaconUrl '...'的值)
将这些值保存为预填值,以便在阶段 3 中使用。如果任一值缺失或使用了占位符(例如 YOUR_APPLICATION_ID),则视为未找到。继续进入阶段 3。
阶段 3:收集输入
首先,只询问以下内容:
applicationId——Dynatrace 应用 ID。告知用户可在其 Dynatrace 租户中已创建的移动应用内找到此 ID。如果在阶段 2 中提取到了值,请将其显示为当前值,并询问用户确认或替换。beaconUrl——Dynatrace Beacon URL。告知用户也可在其 Dynatrace 租户中同一移动应用的配置内找到此 URL。同样,如果有提取到的值,请显示并请用户确认或替换。
用户确认或提供两项内容后,再询问以下问题——除非用户已在初始请求中说明了会话回放偏好;如果已说明,则跳过此问题并采用用户的选择:
- 会话回放——是否启用会话回放?(是/否)
阶段 4:定位文件
查找应用模块
应用模块不一定名为 app。请读取 settings.gradle.kts 或 settings.gradle,查找所有包含的模块,然后检查每个模块的构建文件,确认其是否应用了 com.android.application 插件。将第一个应用此插件的模块所在目录用作下文所有路径中的 APP_MODULE。
macOS / Linux:
grep -r -l --include="*.gradle" --include="*.gradle.kts" --exclude-dir=buildSrc "com.android.application" .
Windows(cmd):
findstr /s /m "com.android.application" *.gradle *.gradle.kts
Windows(PowerShell):
Get-ChildItem -Recurse -Include "*.gradle","*.gradle.kts" | Select-String "com.android.application" | Select-Object -ExpandProperty Path
丢弃匹配行中包含 apply false 的结果——这些是根构建文件中的版本目录声明,并非实际应用的插件。同时丢弃 buildSrc/ 下的所有结果。
如果筛选后仍未找到应用 com.android.application 的模块,请停止并报告失败——此时尚未修改任何文件。
编辑前要读取的文件
- 根目录
build.gradle.kts/build.gradle(与 settings 文件同级) - 应用模块
APP_MODULE/build.gradle.kts/APP_MODULE/build.gradle - 入口源文件——见下文
查找入口文件
首选:Application 类。 根据操作系统使用相应命令,在源代码树中搜索继承 Application 的类:
macOS / Linux:
grep -r -l --include="*.java" "extends Application" APP_MODULE/src
grep -r -l --include="*.kt" ": Application()" APP_MODULE/src
Windows(cmd):
findstr /s /m "extends Application" APP_MODULE\src\*.java
findstr /s /m ": Application()" APP_MODULE\src\*.kt
Windows(PowerShell):
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.java" | Select-String "extends Application" | Select-Object -ExpandProperty Path
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.kt" | Select-String ": Application()" | Select-Object -ExpandProperty Path
如果找到,请使用该文件。在其 onCreate() 中、super.onCreate() 之后添加隐私选择加入调用。
备用方案:启动器 Activity。 如果不存在 Application 类,请在 AndroidManifest.xml 中查找启动器 Activity——它是包含以下内容的 <activity>:
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
读取该 Activity 的 android:name 属性,找到其源文件,并在 onCreate() 中、setContentView(...) 之后添加隐私选择加入调用。
找到文件后,根据扩展名判断语言:.kt = Kotlin,.java = Java。
不要假定文件名是
MainActivity。
第 5 阶段:插桩
对于以下每个步骤,写入前都要检查相应元素是否已存在。如果存在且正确,则跳过。如果存在但不正确或不完整,则仅更新受影响的值。如果不存在,则完整添加。
编辑任何文件之前,先记录其原始内容。如果任何步骤因任何原因失败(构建错误、文件缺失、冲突无法解决、文件结构异常等):
- 立即停止——不要尝试进一步修改。
- 报告失败——明确说明失败的步骤及原因。
- 回滚所有编辑——将本阶段修改的每个文件恢复为原始内容。如果文件是从头创建的,则将其删除。
- 确认回滚——告知用户已恢复哪些文件,并确认项目已恢复到原始状态。
不要让项目处于只完成部分插桩的状态。
根构建文件
首先检查根构建文件是 build.gradle.kts(Kotlin DSL)还是 build.gradle(Groovy DSL),并应用相应语法。
com.dynatrace.instrumentation必须应用在根构建文件中,而不是应用模块中。
Kotlin DSL(build.gradle.kts)
Classpath 依赖——检查 com.dynatrace.tools.android:gradle-plugin 是否已出现在 buildscript { dependencies { } } 块中。如果已存在且版本规范为 8.+,则跳过。如果已存在但版本不同,则将版本更新为 8.+。如果不存在,则在已有的 buildscript { dependencies { } } 块中添加该 classpath;如果不存在这样的块,则在 plugins {} 块之前添加完整的 buildscript 块:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.dynatrace.tools.android:gradle-plugin:8.+")
}
}
应用插件——检查 apply(plugin = "com.dynatrace.instrumentation") 是否已存在。如果已存在,则跳过。如果不存在,则在 plugins {} 块之后添加。
DynatraceExtension 块——检查是否已存在 configure<com.dynatrace.tools.android.dsl.DynatraceExtension> 块。
- 如果已存在,检查每个字段,并仅更新与目标值不同的字段:
applicationId、beaconUrl、userOptIn(true)、agentBehavior.startupLoadBalancing(true)、agentBehavior.startupWithGrailEnabled(true),以及sessionReplay.enabled(true)(如果请求启用会话回放)。添加所有缺失字段。 - 如果不存在,则在应用插件的行之后添加完整代码块。两种情况下,都要将
applicationId和beaconUrl替换为第 3 阶段确认的值——不要保留下面的占位符:
configure<com.dynatrace.tools.android.dsl.DynatraceExtension> {
configurations {
create("sampleConfig") {
autoStart {
applicationId("YOUR_APPLICATION_ID")
beaconUrl("https://your-tenant.live.dynatrace.com/mbeacon")
}
userOptIn(true)
agentBehavior.startupLoadBalancing(true)
agentBehavior.startupWithGrailEnabled(true)
// only if session replay was requested:
sessionReplay.enabled(true)
}
}
}
Groovy DSL (build.gradle)
Classpath 依赖 — 检查 buildscript { dependencies { } } 块中是否已存在 com.dynatrace.tools.android:gradle-plugin。如果存在且版本规范为 8.+,则跳过。如果存在但版本不同,则将版本更新为 8.+。如果不存在,则将 classpath 添加到现有的 buildscript { dependencies { } } 块中;如果没有此块,则在任何 apply 行之前创建完整的 buildscript 块:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.dynatrace.tools.android:gradle-plugin:8.+'
}
}
应用插件 — 检查是否已存在 apply plugin: 'com.dynatrace.instrumentation'。如果存在,则跳过。如果不存在,则将其添加到现有 apply 行之后,或添加到文件末尾。
dynatrace 块 — 检查是否已存在 dynatrace { } 块。
- 如果存在,检查每个字段,并仅更新与目标值不同的字段:
applicationId、beaconUrl、userOptIn true、agentBehavior.startupLoadBalancing true、agentBehavior.startupWithGrailEnabled true,以及sessionReplay.enabled true(如果已请求启用会话回放)。添加任何缺失的字段。 - 如果不存在,则在应用插件的行之后添加完整的块。在这两种情况下,都要将
applicationId和beaconUrl替换为 Phase 3 中确认的值——不要保留下面的占位符:
dynatrace {
configurations {
sampleConfig {
autoStart {
applicationId 'YOUR_APPLICATION_ID'
beaconUrl 'https://your-tenant.live.dynatrace.com/mbeacon'
}
userOptIn true
agentBehavior.startupLoadBalancing true
agentBehavior.startupWithGrailEnabled true
// only if session replay was requested:
sessionReplay.enabled true
}
}
}
入口点文件(Application 类或启动器 Activity)
仅添加尚不存在的导入。对于隐私选择加入调用,检查 onCreate 中是否已存在 Dynatrace.applyUserPrivacyOptions(...)。如果存在,请核对每个选项(DataCollectionLevel.USER_BEHAVIOR、withCrashReportingOptedIn(true),以及启用会话回放时的 withScreenRecordOptedIn(true)),并更新所有不一致的选项。如果不存在,则根据入口点类型,在相应位置插入:
- Application 子类 — 在
super.onCreate()之后 - 启动器 Activity — 在
setContentView(...)之后
Kotlin
导入 — 仅添加尚不存在的导入:
import com.dynatrace.android.agent.Dynatrace
import com.dynatrace.android.agent.conf.DataCollectionLevel
import com.dynatrace.android.agent.conf.UserPrivacyOptions
隐私选择加入调用 — 在 super.onCreate()(Application 子类)之后或 setContentView(...)(启动器 Activity)之后插入。仅当 Phase 3 中启用了会话回放时,才包含 .withScreenRecordOptedIn(true):
Dynatrace.applyUserPrivacyOptions(
UserPrivacyOptions.builder()
.withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
.withCrashReportingOptedIn(true)
// .withScreenRecordOptedIn(true) — add only if session replay is enabled
.build()
)
Java
导入 — 仅添加尚不存在的导入:
import com.dynatrace.android.agent.Dynatrace;
import com.dynatrace.android.agent.conf.DataCollectionLevel;
import com.dynatrace.android.agent.conf.UserPrivacyOptions;
隐私选择加入调用 — 在 super.onCreate()(Application 子类)之后或 setContentView(...)(启动器 Activity)之后插入。仅当 Phase 3 中启用了会话回放时,才包含 .withScreenRecordOptedIn(true):
Dynatrace.applyUserPrivacyOptions(UserPrivacyOptions.builder()
.withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
.withCrashReportingOptedIn(true)
// .withScreenRecordOptedIn(true) — add only if session replay is enabled
.build()
);
Phase 6:构建和验证
首先,查找可用的 assemble 任务,以便处理使用自定义构建类型或产品风味的项目:
macOS / Linux:
./gradlew tasks --group=build | grep -i "^assemble"
Windows(cmd):
gradlew.bat tasks --group=build | findstr /i "assemble"
Windows(PowerShell):
.\gradlew.bat tasks --group=build | Select-String -Pattern "^assemble" -CaseSensitive:$false
如果只列出一个 assemble 任务,则使用该任务。如果列出多个任务,则将它们展示给用户,并询问要运行哪一个。
然后运行该任务:
- macOS / Linux:
./gradlew CHOSEN_TASK - Windows(cmd):
gradlew.bat CHOSEN_TASK - Windows(PowerShell):
.\gradlew.bat CHOSEN_TASK
构建成功即可确认 Dynatrace 插件已正确配置。