├── LICENSE ├── README.md ├── argus-apm-gradle-asm ├── .gitignore ├── README.md ├── bintray.gradle ├── build.gradle ├── config.properties ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── kotlin │ └── com │ │ └── argusapm │ │ └── gradle │ │ ├── AppConstant.kt │ │ ├── ArgusAPMPlugin.kt │ │ ├── ArgusAPMTransform.kt │ │ ├── ArgusApmConfig.kt │ │ └── internal │ │ ├── ArgusDependencyResolutionListener.kt │ │ ├── BuildTimeListener.kt │ │ ├── PluginConfig.kt │ │ ├── asm │ │ ├── ASMWeaver.kt │ │ ├── ExtendClassWriter.kt │ │ └── bytecode │ │ │ ├── BaseClassVisitor.kt │ │ │ ├── ClassFile.kt │ │ │ ├── func │ │ │ ├── FuncClassAdapter.kt │ │ │ └── FuncMethodAdapter.kt │ │ │ ├── net │ │ │ ├── NetClassAdapter.kt │ │ │ ├── NetConstans.kt │ │ │ └── NetMethodAdapter.kt │ │ │ ├── okhttp3 │ │ │ ├── OkHttp3ClassAdapter.kt │ │ │ └── Okhttp3MethodAdapter.kt │ │ │ └── webview │ │ │ ├── WebClassAdapter.kt │ │ │ └── WebMethodAdapter.kt │ │ ├── concurrent │ │ ├── ITask.kt │ │ └── ThreadPool.kt │ │ └── utils │ │ ├── FileUtils.kt │ │ ├── Logging.kt │ │ └── TypeUtil.kt │ └── resources │ └── META-INF │ └── gradle-plugins │ └── argusapm.properties ├── argus-apm-gradle ├── .gitignore ├── README.md ├── bintray.gradle ├── build.gradle ├── config.properties ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libs │ └── aspectjtools.jar └── src │ └── main │ ├── kotlin │ └── com │ │ └── argusapm │ │ └── gradle │ │ ├── AppConstant.kt │ │ ├── ArgusApmConfig.kt │ │ ├── AspectJPlugin.kt │ │ ├── AspectJTransform.kt │ │ └── internal │ │ ├── ArgusDependencyResolutionListener.kt │ │ ├── AspectJClassVisitor.kt │ │ ├── BuildTimeListener.kt │ │ ├── FileType.kt │ │ ├── JarMerger.kt │ │ ├── PluginConfig.kt │ │ ├── ajc │ │ ├── AjcWeaver.kt │ │ └── AjcWeaverManager.kt │ │ ├── concurrent │ │ ├── ITask.kt │ │ └── ThreadPool.kt │ │ ├── cutter │ │ ├── FileFilter.kt │ │ ├── InputSourceCutter.kt │ │ └── InputSourceFileStatus.kt │ │ └── utils │ │ ├── Logger.kt │ │ ├── Utils.kt │ │ └── VariantUtils.kt │ └── resources │ └── META-INF │ └── gradle-plugins │ └── argusapm.properties ├── argus-apm ├── .gitignore ├── README.md ├── argus-apm-aop │ ├── .gitignore │ ├── argus-apm-aop.pro │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── argusapm │ │ └── android │ │ └── aop │ │ ├── TraceActivity.java │ │ └── TraceNetTrafficMonitor.java ├── argus-apm-cloud-dummy-impl │ ├── .gitignore │ ├── argus-apm-cloud-dummy-impl.pro │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── argus_apm_sdk_config.json │ │ ├── java │ │ └── com │ │ │ └── argusapm │ │ │ └── android │ │ │ └── network │ │ │ ├── cloudrule │ │ │ └── RuleSyncRequest.java │ │ │ └── upload │ │ │ └── CollectDataSyncUpload.java │ │ └── res │ │ └── values │ │ └── strings.xml ├── argus-apm-cloud │ ├── .gitignore │ ├── argus-apm-cloud-rules.pro │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── argusapm │ │ │ └── android │ │ │ └── network │ │ │ ├── DebugConfig.java │ │ │ ├── IRuleRequest.java │ │ │ └── IUpload.java │ │ └── res │ │ └── values │ │ └── strings.xml ├── argus-apm-main │ ├── .gitignore │ ├── argus-apm-main.pro │ ├── bintray.gradle │ ├── build.gradle │ ├── libs │ │ ├── argus-apm-cloud-dummy-impl.jar │ │ └── argus-apm-cloud.jar │ ├── sdk_utils.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── argusapm │ │ │ └── android │ │ │ ├── Env.java │ │ │ ├── aop │ │ │ ├── IActivityHelper.java │ │ │ └── IAopTraceHelper.java │ │ │ ├── api │ │ │ ├── ApmTask.java │ │ │ ├── Client.java │ │ │ ├── ExtraDataType.java │ │ │ └── IExtraDataCallback.java │ │ │ ├── cleaner │ │ │ └── DataCleaner.java │ │ │ ├── cloudconfig │ │ │ ├── ArgusApmConfigManager.java │ │ │ ├── Constant.java │ │ │ └── data │ │ │ │ ├── ArgusApmConfigCore.java │ │ │ │ ├── ArgusApmConfigData.java │ │ │ │ └── ArgusApmConfigFuncControl.java │ │ │ ├── core │ │ │ ├── BaseInfo.java │ │ │ ├── Config.java │ │ │ ├── IInfo.java │ │ │ ├── Manager.java │ │ │ ├── ReceiverManager.java │ │ │ ├── StorageConfig.java │ │ │ ├── TaskConfig.java │ │ │ ├── job │ │ │ │ ├── activity │ │ │ │ │ ├── AH.java │ │ │ │ │ ├── ActivityCore.java │ │ │ │ │ ├── ActivityCounter.java │ │ │ │ │ ├── ActivityHelper.java │ │ │ │ │ ├── ActivityInfo.java │ │ │ │ │ ├── ActivityStorage.java │ │ │ │ │ ├── ActivityTable.java │ │ │ │ │ ├── ActivityTask.java │ │ │ │ │ ├── ApmInstrumentation.java │ │ │ │ │ └── InstrumentationHooker.java │ │ │ │ ├── anr │ │ │ │ │ ├── AnrFileParser.java │ │ │ │ │ ├── AnrFileTask.java │ │ │ │ │ ├── AnrInfo.java │ │ │ │ │ ├── AnrLoopTask.java │ │ │ │ │ └── AnrTask.java │ │ │ │ ├── appstart │ │ │ │ │ ├── AppStartInfo.java │ │ │ │ │ ├── AppStartStorage.java │ │ │ │ │ ├── AppStartTable.java │ │ │ │ │ └── AppStartTask.java │ │ │ │ ├── block │ │ │ │ │ ├── BlockInfo.java │ │ │ │ │ ├── BlockStorage.java │ │ │ │ │ ├── BlockTable.java │ │ │ │ │ └── BlockTask.java │ │ │ │ ├── fileinfo │ │ │ │ │ ├── FileInfo.java │ │ │ │ │ ├── FileInfoStorage.java │ │ │ │ │ ├── FileInfoTask.java │ │ │ │ │ └── FileTable.java │ │ │ │ ├── fps │ │ │ │ │ ├── FpsInfo.java │ │ │ │ │ ├── FpsStorage.java │ │ │ │ │ ├── FpsTable.java │ │ │ │ │ └── FpsTask.java │ │ │ │ ├── func │ │ │ │ │ ├── AopFuncTrace.java │ │ │ │ │ ├── FuncInfo.java │ │ │ │ │ ├── FuncStorage.java │ │ │ │ │ ├── FuncTable.java │ │ │ │ │ ├── FuncTask.java │ │ │ │ │ └── FuncTrace.java │ │ │ │ ├── memory │ │ │ │ │ ├── MemStorage.java │ │ │ │ │ ├── MemoryInfo.java │ │ │ │ │ ├── MemoryTable.java │ │ │ │ │ └── MemoryTask.java │ │ │ │ ├── net │ │ │ │ │ ├── NetInfo.java │ │ │ │ │ ├── NetStorage.java │ │ │ │ │ ├── NetTable.java │ │ │ │ │ ├── NetTask.java │ │ │ │ │ ├── i │ │ │ │ │ │ ├── IStreamCompleteListener.java │ │ │ │ │ │ ├── QHC.java │ │ │ │ │ │ ├── QOKHttp.java │ │ │ │ │ │ └── QURL.java │ │ │ │ │ └── impl │ │ │ │ │ │ ├── AopHttpClient.java │ │ │ │ │ │ ├── AopHttpEntity.java │ │ │ │ │ │ ├── AopHttpRequestEntity.java │ │ │ │ │ │ ├── AopHttpResponseEntity.java │ │ │ │ │ │ ├── AopHttpURLConnection.java │ │ │ │ │ │ ├── AopHttpsURLConnection.java │ │ │ │ │ │ ├── AopInputStream.java │ │ │ │ │ │ ├── AopOutputStream.java │ │ │ │ │ │ ├── AopResponseHandler.java │ │ │ │ │ │ └── AopURL.java │ │ │ │ ├── processinfo │ │ │ │ │ ├── ProcessInfo.java │ │ │ │ │ ├── ProcessInfoStorage.java │ │ │ │ │ ├── ProcessInfoTask.java │ │ │ │ │ └── ProgessInfoTable.java │ │ │ │ ├── watchDog │ │ │ │ │ ├── WatchDogInfo.java │ │ │ │ │ ├── WatchDogInfoStorage.java │ │ │ │ │ ├── WatchDogInfoTable.java │ │ │ │ │ └── WatchDogTask.java │ │ │ │ └── webview │ │ │ │ │ ├── AopWebTrace.java │ │ │ │ │ ├── JSBridge.java │ │ │ │ │ ├── WebInfo.java │ │ │ │ │ ├── WebStorage.java │ │ │ │ │ ├── WebTable.java │ │ │ │ │ ├── WebTask.java │ │ │ │ │ └── WebTrace.java │ │ │ ├── storage │ │ │ │ ├── ApmProvider.java │ │ │ │ ├── DataHelper.java │ │ │ │ ├── DbCache.java │ │ │ │ ├── DbHelper.java │ │ │ │ ├── DbSwitch.java │ │ │ │ ├── IStorage.java │ │ │ │ ├── ITable.java │ │ │ │ ├── StorageUtils.java │ │ │ │ └── TableStorage.java │ │ │ └── tasks │ │ │ │ ├── BaseTask.java │ │ │ │ ├── ITask.java │ │ │ │ └── TaskManager.java │ │ │ ├── debug │ │ │ ├── AnalyzeManager.java │ │ │ ├── callback │ │ │ │ └── IDebugCallback.java │ │ │ ├── config │ │ │ │ └── DebugConfig.java │ │ │ ├── output │ │ │ │ └── OutputProxy.java │ │ │ ├── storage │ │ │ │ ├── IOUtil.java │ │ │ │ ├── StorageManager.java │ │ │ │ └── TraceWriter.java │ │ │ ├── tasks │ │ │ │ ├── ActivityParseTask.java │ │ │ │ ├── AppStartParseTask.java │ │ │ │ ├── FpsParseTask.java │ │ │ │ ├── IParser.java │ │ │ │ ├── MemoryParseTask.java │ │ │ │ ├── MonitorParseTask.java │ │ │ │ └── NetParseTask.java │ │ │ ├── utils │ │ │ │ └── DebugFloatWindowUtls.java │ │ │ └── view │ │ │ │ ├── BigFloatWindowView.java │ │ │ │ ├── FloatWindowManager.java │ │ │ │ ├── SmallFloatWindowView.java │ │ │ │ └── component │ │ │ │ └── CircleView.java │ │ │ ├── helper │ │ │ └── ApmDebugEnable.java │ │ │ ├── network │ │ │ ├── CloudRule.java │ │ │ ├── UploadConfig.java │ │ │ ├── UploadInfoField.java │ │ │ └── UploadManager.java │ │ │ └── utils │ │ │ ├── AspectjUtils.java │ │ │ ├── AsyncThreadTask.java │ │ │ ├── CommonUtils.java │ │ │ ├── ExtraInfoHelper.java │ │ │ ├── FileUtils.java │ │ │ ├── FloatWindowUtils.java │ │ │ ├── IOStreamUtils.java │ │ │ ├── LogX.java │ │ │ ├── PreferenceUtils.java │ │ │ ├── ProcessUtils.java │ │ │ ├── RootHelper.java │ │ │ └── SystemUtils.java │ │ └── res │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ └── strings.xml ├── argus-apm-okhttp │ ├── .gitignore │ ├── argus-apm-okhttp.pro │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── argusapm │ │ │ └── android │ │ │ └── okhttp3 │ │ │ ├── DataRecordUtils.java │ │ │ ├── Env.java │ │ │ ├── NetWorkInterceptor.java │ │ │ ├── OkHttp3Aspect.java │ │ │ ├── OkHttpData.java │ │ │ └── OkHttpUtils.java │ │ └── res │ │ └── values │ │ └── strings.xml ├── argus-apm-sample │ ├── .gitignore │ ├── argusapm.gradle │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── demotest.exe │ │ ├── java │ │ └── com │ │ │ └── argusapm │ │ │ └── sample │ │ │ ├── ArgusAPMApplication.java │ │ │ ├── MainActivity.java │ │ │ ├── test │ │ │ ├── TestActivity.java │ │ │ ├── TestBlockActivity.java │ │ │ ├── TestOkHttp3Activity.java │ │ │ └── TestUrlConnection.java │ │ │ └── utils │ │ │ ├── DownloadUtil.java │ │ │ ├── FileUtils.java │ │ │ ├── HttpHelper.java │ │ │ └── ProcessUtils.java │ │ └── res │ │ ├── drawable │ │ └── cloud.png │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_second.xml │ │ ├── activity_test.xml │ │ ├── activity_test_block.xml │ │ ├── activity_test_ok_http3.xml │ │ └── activity_web.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle └── doc └── img └── readme ├── 201736165776251_meitu_1.jpg ├── AJC织入.png ├── ArgusAPM.jpeg ├── ArgusAPM架构图.png ├── ArgusAPM详细设计图.png ├── Gradle_APM.png ├── apm启动成功.PNG ├── appstore.png ├── camera.png ├── clean.png ├── mobilesafe.png ├── movie.png ├── qizhuoshe_258.jpg ├── qizhuoshe_344.jpg ├── qrcode_1542008553175.jpg └── 新的APM接入方式 .png /argus-apm-gradle-asm/README.md: -------------------------------------------------------------------------------- 1 | # Argus APM Gradle 2 | -------------------------------------------------------------------------------- /argus-apm-gradle-asm/bintray.gradle: -------------------------------------------------------------------------------- 1 | // 应用插件 2 | apply plugin: 'com.jfrog.bintray' 3 | apply plugin: 'maven-publish' 4 | 5 | 6 | def baseUrl = 'https://github.com/Qihoo360/ArgusApm' 7 | def siteUrl = baseUrl 8 | def gitUrl = "${baseUrl}/ArgusApm" 9 | def issueUrl = "${gitUrl}/issues" 10 | 11 | 12 | 13 | install { 14 | repositories { 15 | mavenInstaller { 16 | // This generates POM.xml with proper paramters 17 | pom.project { 18 | 19 | //添加项目描述 20 | name 'Gradle Plugin for Android' 21 | url siteUrl 22 | //设置开源证书信息 23 | licenses { 24 | license { 25 | name 'The Apache Software License, Version 2.0' 26 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 27 | } 28 | } 29 | //添加开发者信息 30 | developers { 31 | developer { 32 | name 'argusapm' 33 | email 'argusapm@gmail.com' 34 | } 35 | } 36 | 37 | scm { 38 | connection gitUrl 39 | developerConnection gitUrl 40 | url siteUrl 41 | } 42 | } 43 | } 44 | 45 | } 46 | } 47 | 48 | // 强制 Java/JavaDoc 等的编码为 UTF-8 49 | tasks.withType(JavaCompile) { 50 | options.encoding = "UTF-8" 51 | } 52 | 53 | task javadocJar(type: Jar, dependsOn: javadoc) { 54 | classifier = 'javadoc' 55 | from javadoc.destinationDir 56 | } 57 | 58 | artifacts { 59 | archives javadocJar 60 | archives sourcesJar 61 | } 62 | 63 | //配置上传Bintray相关信息 64 | bintray { 65 | user = BINTRAY_USER 66 | key = BINTRAY_APIKEY 67 | 68 | configurations = ['archives'] 69 | pkg { 70 | repo = 'argusapm' // 上传到中央仓库的名称 71 | name = 'argus-apm-gradle' // 上传到jcenter 的项目名称 72 | userOrg = 'argusapm' 73 | desc = 'ArgusApm - A flexible, stable, easy-to-use Android Performence Library' // 项目描述 74 | websiteUrl = siteUrl 75 | issueTrackerUrl = issueUrl 76 | vcsUrl = gitUrl 77 | labels = ['gradle', 'plugin', 'argus', 'apm'] 78 | licenses = ['Apache-2.0'] 79 | publish = true 80 | } 81 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.30' 3 | repositories { 4 | mavenLocal() 5 | jcenter() 6 | maven { 7 | url 'https://maven.google.com/' 8 | name 'Google' 9 | } 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:3.1.3' 13 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 15 | } 16 | } 17 | 18 | 19 | apply plugin: 'kotlin' 20 | apply plugin: 'maven' 21 | apply plugin: 'com.jfrog.bintray' 22 | 23 | project.ext { 24 | aspectjVersion = '1.8.12' 25 | } 26 | 27 | dependencies { 28 | repositories { 29 | mavenLocal() 30 | jcenter() 31 | mavenCentral() 32 | maven { url 'https://maven.google.com' } 33 | maven { url 'http://repository.jetbrains.com/utils' } 34 | maven { url "https://dl.bintray.com/archinamon/maven" } 35 | } 36 | 37 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 38 | compileOnly gradleApi() 39 | compileOnly 'com.android.tools.build:gradle:3.1.3' 40 | compile "org.ow2.asm:asm:7.0" 41 | compile "org.ow2.asm:asm-commons:7.0" 42 | } 43 | 44 | group = 'com.qihoo360.argusapm' 45 | version = '3.0.1.1001' 46 | 47 | task sourcesJar(type: Jar, dependsOn: classes) { 48 | classifier = 'sources' 49 | from sourceSets.main.allSource 50 | } 51 | 52 | apply from: "bintray.gradle" 53 | -------------------------------------------------------------------------------- /argus-apm-gradle-asm/config.properties: -------------------------------------------------------------------------------- 1 | repoUrl= 2 | groupId=com.qihoo360.argus.apm 3 | artifactId=apm-gradle 4 | version=0.0.1 5 | username= 6 | password= 7 | 8 | -------------------------------------------------------------------------------- /argus-apm-gradle-asm/gradle.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm-gradle-asm/gradle.properties -------------------------------------------------------------------------------- /argus-apm-gradle-asm/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm-gradle-asm/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /argus-apm-gradle-asm/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2005-2017 Qihoo 360 Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | # use this file except in compliance with the License. You may obtain a copy of 6 | # the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed To in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations under 14 | # the License. 15 | # 16 | 17 | #Mon Dec 28 10:00:20 PST 2015 18 | distributionBase=GRADLE_USER_HOME 19 | distributionPath=wrapper/dists 20 | zipStoreBase=GRADLE_USER_HOME 21 | zipStorePath=wrapper/dists 22 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 23 | -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/AppConstant.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | object AppConstant { 4 | /** 版本号 */ 5 | const val VER = "3.0.1.1001" 6 | 7 | /** 打印信息时候的前缀 */ 8 | const val TAG = "< argus-apm-v$VER >" 9 | 10 | /** 外部用户配置信息 */ 11 | const val USER_CONFIG = "argusApmAjxConfig" 12 | /** Transform的名字*/ 13 | const val TRANSFORM_NAME = "argus_apm_asm" 14 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/ArgusAPMPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | import com.android.build.gradle.AppExtension 4 | import com.android.build.gradle.AppPlugin 5 | import com.argusapm.gradle.internal.ArgusDependencyResolutionListener 6 | import com.argusapm.gradle.internal.BuildTimeListener 7 | import com.argusapm.gradle.internal.PluginConfig 8 | import org.gradle.api.Plugin 9 | import org.gradle.api.Project 10 | 11 | internal class ArgusAPMPlugin : Plugin { 12 | private lateinit var mProject: Project 13 | override fun apply(project: Project) { 14 | mProject = project 15 | project.extensions.create(AppConstant.USER_CONFIG, ArgusApmConfig::class.java) 16 | PluginConfig.init(project) 17 | //自定义依赖库管理 18 | project.gradle.addListener(ArgusDependencyResolutionListener(project)) 19 | 20 | if (project.plugins.hasPlugin(AppPlugin::class.java)) { 21 | //监听每个任务的执行时间 22 | project.gradle.addListener(BuildTimeListener()) 23 | 24 | val android = project.extensions.getByType(AppExtension::class.java) 25 | android.registerTransform(ArgusAPMTransform(project)) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/ArgusDependencyResolutionListener.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.argusapm.gradle.AppConstant 4 | import org.gradle.api.Project 5 | import org.gradle.api.artifacts.DependencyResolutionListener 6 | import org.gradle.api.artifacts.ResolvableDependencies 7 | 8 | val COMPILE_CONFIGURATIONS = arrayOf("api", "compile") 9 | 10 | /** 11 | * 兼容Compile模式 12 | */ 13 | fun Project.compatCompile(depLib: Any) { 14 | COMPILE_CONFIGURATIONS.find { configurations.findByName(it) != null }?.let { 15 | dependencies.add(it, depLib) 16 | } 17 | } 18 | 19 | class ArgusDependencyResolutionListener(val project: Project) : DependencyResolutionListener { 20 | override fun beforeResolve(dependencies: ResolvableDependencies?) { 21 | if (PluginConfig.argusApmConfig().dependencyEnabled) { 22 | if (PluginConfig.argusApmConfig().debugDependencies.isEmpty() && PluginConfig.argusApmConfig().moduleDependencies.isEmpty()) { 23 | project.compatCompile("com.qihoo360.argusapm:argus-apm-main:${AppConstant.VER}") 24 | if (PluginConfig.argusApmConfig().okhttpEnabled) { 25 | project.compatCompile("com.qihoo360.argusapm:argus-apm-okhttp:${AppConstant.VER}") 26 | } 27 | } else { 28 | //配置本地Module库,方便断点调试 29 | if (PluginConfig.argusApmConfig().moduleDependencies.isNotEmpty()) { 30 | PluginConfig.argusApmConfig().moduleDependencies.forEach { moduleLib: String -> 31 | project.compatCompile(project.project(moduleLib)) 32 | } 33 | } 34 | 35 | //发布Release版本之前,可以使用Debug库测试 36 | if (PluginConfig.argusApmConfig().debugDependencies.isNotEmpty()) { 37 | project.repositories.mavenLocal() 38 | //方便在测试的时候使用,不再需要单独的Gradle发版本 39 | PluginConfig.argusApmConfig().debugDependencies.forEach { debugLib: String -> 40 | project.compatCompile(debugLib) 41 | } 42 | } 43 | } 44 | } 45 | project.gradle.removeListener(this) 46 | } 47 | 48 | override fun afterResolve(dependencies: ResolvableDependencies?) { 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/BuildTimeListener.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.argusapm.gradle.internal.utils.log 4 | import org.gradle.BuildListener 5 | import org.gradle.BuildResult 6 | import org.gradle.api.Task 7 | import org.gradle.api.execution.TaskExecutionListener 8 | import org.gradle.api.initialization.Settings 9 | import org.gradle.api.invocation.Gradle 10 | import org.gradle.api.tasks.TaskState 11 | 12 | class BuildTimeListener : TaskExecutionListener, BuildListener { 13 | 14 | private var startTime: Long = 0L 15 | private var times = mutableListOf>() 16 | 17 | override fun buildStarted(gradle: Gradle) {} 18 | override fun settingsEvaluated(settings: Settings) {} 19 | override fun projectsLoaded(gradle: Gradle) {} 20 | override fun projectsEvaluated(gradle: Gradle) {} 21 | 22 | override fun buildFinished(result: BuildResult) { 23 | log("Task spend time:") 24 | times.filter { it.first > 50 } 25 | .forEach { log("%7sms\t%s".format(it.first, it.second)) } 26 | } 27 | 28 | override fun beforeExecute(task: Task) { 29 | startTime = System.currentTimeMillis() 30 | } 31 | 32 | override fun afterExecute(task: Task, state: TaskState) { 33 | val ms = System.currentTimeMillis() - startTime 34 | times.add(Pair(ms, task.path)) 35 | task.project.logger.warn("${task.path} spend ${ms}ms") 36 | } 37 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/PluginConfig.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.android.build.gradle.AppPlugin 4 | import com.android.build.gradle.LibraryPlugin 5 | import com.argusapm.gradle.ArgusApmConfig 6 | import org.gradle.api.GradleException 7 | import org.gradle.api.Project 8 | 9 | class PluginConfig { 10 | companion object { 11 | lateinit var project: Project 12 | fun init(project: Project) { 13 | val hasAppPlugin = project.plugins.hasPlugin(AppPlugin::class.java) 14 | val hasLibPlugin = project.plugins.hasPlugin(LibraryPlugin::class.java) 15 | if (!hasAppPlugin && !hasLibPlugin) { 16 | throw GradleException("argusapm: The 'com.android.application' or 'com.android.library' plugin is required.") 17 | } 18 | Companion.project = project 19 | } 20 | 21 | fun argusApmConfig(): ArgusApmConfig { 22 | return project.extensions.getByType(ArgusApmConfig::class.java) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/ExtendClassWriter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.asm 2 | 3 | import org.objectweb.asm.ClassWriter 4 | 5 | 6 | class ExtendClassWriter( flags: Int) : ClassWriter(flags) { 7 | 8 | private val DIR_SEPARATOR_UNIX = '/' 9 | private val EXTENSION_SEPARATOR = '.'; 10 | 11 | 12 | override fun getCommonSuperClass(type1: String, type2: String): String? { 13 | try { 14 | var c = Class.forName(type1.replace(DIR_SEPARATOR_UNIX, EXTENSION_SEPARATOR), true, this.classLoader); 15 | val d = Class.forName(type2.replace(DIR_SEPARATOR_UNIX, EXTENSION_SEPARATOR), true, this.classLoader); 16 | if (c.isAssignableFrom(d)) { 17 | return type1; 18 | } 19 | if (d.isAssignableFrom(c)) { 20 | return type2; 21 | } 22 | if (c.isInterface || d.isInterface) { 23 | return "java/lang/Object"; 24 | } 25 | do { 26 | c = c.superclass; 27 | } while (!c.isAssignableFrom(d)); 28 | return c.name.replace(EXTENSION_SEPARATOR, DIR_SEPARATOR_UNIX); 29 | } catch (e: Exception) { 30 | throw RuntimeException(e.toString()); 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/BaseClassVisitor.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.asm.bytecode 2 | 3 | import org.objectweb.asm.ClassVisitor 4 | import org.objectweb.asm.Opcodes 5 | 6 | open class BaseClassVisitor(api: Int, cv: ClassVisitor?) : ClassVisitor(api, cv) { 7 | var className = "" 8 | var isInterface: Boolean = false 9 | override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array?) { 10 | super.visit(version, access, name, signature, superName, interfaces) 11 | this.className = name 12 | this.isInterface = (access and Opcodes.ACC_INTERFACE) != 0 13 | } 14 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/ClassFile.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.asm.bytecode 2 | 3 | import com.argusapm.gradle.internal.utils.log 4 | 5 | class ClassFile { 6 | 7 | companion object { 8 | //子类与父类的对应关系 9 | val sRelationshipMap = HashMap() 10 | 11 | fun classMapReset() { 12 | log("------ classMapSize is ${sRelationshipMap.size}") 13 | sRelationshipMap.clear() 14 | } 15 | 16 | fun classMap(className: String, superClassName: String) { 17 | sRelationshipMap[className] = superClassName 18 | } 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/func/FuncClassAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.asm.bytecode.func 2 | 3 | import com.argusapm.gradle.internal.asm.bytecode.BaseClassVisitor 4 | import com.argusapm.gradle.internal.utils.TypeUtil.Companion.isNeedWeaveMethod 5 | import com.argusapm.gradle.internal.utils.TypeUtil.Companion.isOnReceiveMethod 6 | import com.argusapm.gradle.internal.utils.TypeUtil.Companion.isRunMethod 7 | import org.objectweb.asm.ClassVisitor 8 | import org.objectweb.asm.MethodVisitor 9 | 10 | class FuncClassAdapter(api: Int, cv: ClassVisitor?) : BaseClassVisitor(api, cv) { 11 | override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { 12 | if (isInterface || !isNeedWeaveMethod(className, access)) { 13 | return super.visitMethod(access, name, desc, signature, exceptions); 14 | } 15 | 16 | val mv = cv.visitMethod(access, name, desc, signature, exceptions) 17 | if ((isRunMethod(name, desc) || isOnReceiveMethod(name, desc)) && mv != null) { 18 | return FuncMethodAdapter(className.replace("/", "."), name, desc, api, access, desc, mv) 19 | } 20 | return mv 21 | } 22 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/net/NetClassAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.bytecode.func 2 | 3 | import com.argusapm.gradle.internal.asm.bytecode.BaseClassVisitor 4 | import com.argusapm.gradle.internal.utils.TypeUtil 5 | import org.objectweb.asm.ClassVisitor 6 | import org.objectweb.asm.MethodVisitor 7 | 8 | class NetClassAdapter(api: Int, cv: ClassVisitor?) : BaseClassVisitor(api, cv) { 9 | override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { 10 | if (isInterface || !TypeUtil.isNeedWeaveMethod(className, access)) { 11 | return super.visitMethod(access, name, desc, signature, exceptions); 12 | } 13 | 14 | val mv = cv.visitMethod(access, name, desc, signature, exceptions) 15 | if (mv != null) { 16 | return NetMethodAdapter(api, access, desc, mv) 17 | } 18 | return mv 19 | } 20 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/net/NetConstans.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.asm.bytecode.net 2 | 3 | class NetConstans { 4 | companion object { 5 | const val HTTPCLIENT = "org/apache/http/client/HttpClient" 6 | const val EXECUTE = "execute" 7 | const val REQUEST = "(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/HttpResponse;" 8 | const val REQUEST_CONTEXT = "(Lorg/apache/http/client/methods/HttpUriRequest;Lorg/apache/http/protocol/HttpContext;" 9 | const val REQUEST_RESPONSEHANDLER = "(Lorg/apache/http/client/methods/HttpUriRequest;Lorg/apache/http/client/ResponseHandler;)Ljava/lang/Object;" 10 | const val REQUEST_RESPONSEHANDLER_CONTEXT = "(Lorg/apache/http/client/methods/HttpUriRequest;Lorg/apache/http/client/ResponseHandler;Lorg/apache/http/protocol/HttpContext;)Ljava/lang/Object;" 11 | const val HOST_REQUEST = "(Lorg/apache/http/HttpHost;Lorg/apache/http/HttpRequest;)Lorg/apache/http/HttpResponse;" 12 | const val HOST_REQUEST_CONTEXT = "(Lorg/apache/http/HttpHost;Lorg/apache/http/HttpRequest;Lorg/apache/http/protocol/HttpContext;)Lorg/apache/http/HttpResponse;" 13 | const val HOST_REQUEST_RESPONSEHANDLER = "(Lorg/apache/http/HttpHost;Lorg/apache/http/HttpRequest;Lorg/apache/http/client/ResponseHandler;)Ljava/lang/Object;" 14 | const val HOST_REQUEST_RESPONSEHANDLER_CONTEXT = "(Lorg/apache/http/HttpHost;Lorg/apache/http/HttpRequest;Lorg/apache/http/client/ResponseHandler;Lorg/apache/http/protocol/HttpContext;)Ljava/lang/Object;" 15 | 16 | 17 | const val URL = "java/net/URL" 18 | const val OPEN_CONNECTION = "openConnection" 19 | const val URL_CONNECTION = "()Ljava/net/URLConnection;" 20 | const val URL_CONNECTION_PROXY = "(Ljava/net/Proxy;)Ljava/net/URLConnection;" 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/okhttp3/OkHttp3ClassAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.bytecode.func 2 | 3 | import com.argusapm.gradle.internal.asm.bytecode.BaseClassVisitor 4 | import com.argusapm.gradle.internal.utils.TypeUtil 5 | import org.objectweb.asm.ClassVisitor 6 | import org.objectweb.asm.MethodVisitor 7 | 8 | class OkHttp3ClassAdapter(api: Int, cv: ClassVisitor?) : BaseClassVisitor(api, cv) { 9 | 10 | override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { 11 | if (isInterface || !TypeUtil.isNeedWeaveMethod(className, access)) { 12 | return super.visitMethod(access, name, desc, signature, exceptions); 13 | } 14 | 15 | val mv = cv.visitMethod(access, name, desc, signature, exceptions) 16 | if (TypeUtil.isOkhttpClientBuilder(className) && mv != null) { 17 | return Okhttp3MethodAdapter(name, api, access, desc, mv) 18 | } 19 | return mv 20 | } 21 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/okhttp3/Okhttp3MethodAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.bytecode.func 2 | 3 | import com.argusapm.gradle.internal.utils.TypeUtil 4 | import com.argusapm.gradle.internal.utils.log 5 | import org.objectweb.asm.MethodVisitor 6 | import org.objectweb.asm.Opcodes 7 | import org.objectweb.asm.Opcodes.* 8 | import org.objectweb.asm.commons.LocalVariablesSorter 9 | 10 | class Okhttp3MethodAdapter(private val methodName: String, api: Int, access: Int, private val desc: String, mv: MethodVisitor?) : LocalVariablesSorter(api, access, desc, mv) { 11 | 12 | override fun visitInsn(opcode: Int) { 13 | if (isReturn(opcode) && TypeUtil.isOkhttpClientBuild(methodName, desc)) { 14 | mv.visitVarInsn(ALOAD, 0) 15 | mv.visitFieldInsn(GETFIELD, "okhttp3/OkHttpClient\$Builder", "interceptors", "Ljava/util/List;") 16 | mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/argusapm/android/okhttp3/OkHttpUtils", "insertToOkHttpClientBuilder", "(Ljava/util/List;)V", false) 17 | } 18 | super.visitInsn(opcode) 19 | } 20 | 21 | private fun isReturn(opcode: Int): Boolean { 22 | return ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) 23 | } 24 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/webview/WebClassAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.bytecode.func 2 | 3 | import com.argusapm.gradle.internal.asm.bytecode.BaseClassVisitor 4 | import com.argusapm.gradle.internal.utils.TypeUtil 5 | import org.objectweb.asm.ClassVisitor 6 | import org.objectweb.asm.MethodVisitor 7 | 8 | 9 | class WebClassAdapter(api: Int, cv: ClassVisitor?) : BaseClassVisitor(api, cv) { 10 | 11 | override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { 12 | if (isInterface || !TypeUtil.isNeedWeaveMethod(className, access)) { 13 | return super.visitMethod(access, name, desc, signature, exceptions); 14 | } 15 | 16 | val mv = cv.visitMethod(access, name, desc, signature, exceptions) 17 | if (TypeUtil.isOnPageFinishedMethod(name, desc)) { 18 | if (mv != null) { 19 | return WebMethodAdapter(name, desc, api, access, desc, mv) 20 | } 21 | } 22 | return mv 23 | } 24 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/asm/bytecode/webview/WebMethodAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.bytecode.func 2 | 3 | import org.objectweb.asm.Label 4 | import org.objectweb.asm.MethodVisitor 5 | import org.objectweb.asm.Opcodes.* 6 | import org.objectweb.asm.commons.LocalVariablesSorter 7 | 8 | class WebMethodAdapter(private val methodName: String, private val methodDesc: String, api: Int, access: Int, desc: String?, mv: MethodVisitor?) : LocalVariablesSorter(api, access, desc, mv) { 9 | override fun visitCode() { 10 | 11 | mv.visitVarInsn(ALOAD, 1) 12 | mv.visitMethodInsn(INVOKEVIRTUAL, "android/webkit/WebView", "getProgress", "()I", false) 13 | mv.visitIntInsn(BIPUSH, 100) 14 | val l0 = Label() 15 | mv.visitJumpInsn(IF_ICMPNE, l0) 16 | mv.visitVarInsn(ALOAD, 1) 17 | mv.visitMethodInsn(INVOKEVIRTUAL, "android/webkit/WebView", "getSettings", "()Landroid/webkit/WebSettings;", false) 18 | mv.visitVarInsn(ASTORE, 3) 19 | mv.visitVarInsn(ALOAD, 3) 20 | mv.visitInsn(ICONST_1) 21 | mv.visitMethodInsn(INVOKEVIRTUAL, "android/webkit/WebSettings", "setJavaScriptEnabled", "(Z)V", false) 22 | mv.visitVarInsn(ALOAD, 1) 23 | mv.visitTypeInsn(NEW, "com/argusapm/android/core/job/webview/JSBridge") 24 | mv.visitInsn(DUP) 25 | mv.visitVarInsn(ALOAD, 2) 26 | mv.visitMethodInsn(INVOKESPECIAL, "com/argusapm/android/core/job/webview/JSBridge", "", "(Ljava/lang/String;)V", false) 27 | mv.visitLdcInsn("android_apm") 28 | mv.visitMethodInsn(INVOKEVIRTUAL, "android/webkit/WebView", "addJavascriptInterface", "(Ljava/lang/Object;Ljava/lang/String;)V", false) 29 | mv.visitLdcInsn("javascript:%s.sendResource(JSON.stringify(window.performance.timing));") 30 | mv.visitInsn(ICONST_1) 31 | mv.visitTypeInsn(ANEWARRAY, "java/lang/Object") 32 | mv.visitInsn(DUP) 33 | mv.visitInsn(ICONST_0) 34 | mv.visitLdcInsn("android_apm") 35 | mv.visitInsn(AASTORE) 36 | mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", false) 37 | mv.visitVarInsn(ASTORE, 4) 38 | mv.visitVarInsn(ALOAD, 1) 39 | mv.visitVarInsn(ALOAD, 4) 40 | mv.visitMethodInsn(INVOKEVIRTUAL, "android/webkit/WebView", "loadUrl", "(Ljava/lang/String;)V", false) 41 | mv.visitLabel(l0) 42 | 43 | super.visitCode() 44 | } 45 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/concurrent/ITask.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.concurrent 2 | 3 | import java.util.concurrent.Callable 4 | 5 | interface ITask : Callable -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/concurrent/ThreadPool.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.concurrent 2 | 3 | import java.util.concurrent.Executors 4 | 5 | class ThreadPool { 6 | private val executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() + 1) 7 | val taskList = arrayListOf() 8 | 9 | fun addTask(task: ITask) { 10 | taskList.add(task) 11 | } 12 | 13 | fun startWork() { 14 | executorService.invokeAll(taskList) 15 | taskList.clear() 16 | } 17 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/kotlin/com/argusapm/gradle/internal/utils/Logging.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.utils 2 | 3 | import com.argusapm.gradle.AppConstant 4 | 5 | 6 | fun log(msg: String) { 7 | kotlin.io.println("ArgusAPM V${AppConstant.VER}:-->$msg") 8 | } -------------------------------------------------------------------------------- /argus-apm-gradle-asm/src/main/resources/META-INF/gradle-plugins/argusapm.properties: -------------------------------------------------------------------------------- 1 | implementation-class=com.argusapm.gradle.ArgusAPMPlugin -------------------------------------------------------------------------------- /argus-apm-gradle/README.md: -------------------------------------------------------------------------------- 1 | # Argus APM Gradle 2 | -------------------------------------------------------------------------------- /argus-apm-gradle/bintray.gradle: -------------------------------------------------------------------------------- 1 | // 应用插件 2 | apply plugin: 'com.jfrog.bintray' 3 | apply plugin: 'maven-publish' 4 | 5 | 6 | def baseUrl = 'https://github.com/Qihoo360/ArgusApm' 7 | def siteUrl = baseUrl 8 | def gitUrl = "${baseUrl}/ArgusApm" 9 | def issueUrl = "${gitUrl}/issues" 10 | 11 | 12 | 13 | install { 14 | repositories { 15 | mavenInstaller { 16 | // This generates POM.xml with proper paramters 17 | pom.project { 18 | 19 | //添加项目描述 20 | name 'Gradle Plugin for Android' 21 | url siteUrl 22 | //设置开源证书信息 23 | licenses { 24 | license { 25 | name 'The Apache Software License, Version 2.0' 26 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 27 | } 28 | } 29 | //添加开发者信息 30 | developers { 31 | developer { 32 | name 'argusapm' 33 | email 'argusapm@gmail.com' 34 | } 35 | } 36 | 37 | scm { 38 | connection gitUrl 39 | developerConnection gitUrl 40 | url siteUrl 41 | } 42 | } 43 | } 44 | 45 | } 46 | } 47 | 48 | // 强制 Java/JavaDoc 等的编码为 UTF-8 49 | tasks.withType(JavaCompile) { 50 | options.encoding = "UTF-8" 51 | } 52 | 53 | task javadocJar(type: Jar, dependsOn: javadoc) { 54 | classifier = 'javadoc' 55 | from javadoc.destinationDir 56 | } 57 | 58 | artifacts { 59 | archives javadocJar 60 | archives sourcesJar 61 | } 62 | 63 | //配置上传Bintray相关信息 64 | bintray { 65 | user = BINTRAY_USER 66 | key = BINTRAY_APIKEY 67 | 68 | configurations = ['archives'] 69 | pkg { 70 | repo = 'argusapm' // 上传到中央仓库的名称 71 | name = 'argus-apm-gradle' // 上传到jcenter 的项目名称 72 | userOrg = 'argusapm' 73 | desc = 'ArgusApm - A flexible, stable, easy-to-use Android Performence Library' // 项目描述 74 | websiteUrl = siteUrl 75 | issueTrackerUrl = issueUrl 76 | vcsUrl = gitUrl 77 | labels = ['gradle', 'plugin', 'argus', 'apm'] 78 | licenses = ['Apache-2.0'] 79 | publish = true 80 | } 81 | } -------------------------------------------------------------------------------- /argus-apm-gradle/config.properties: -------------------------------------------------------------------------------- 1 | repoUrl= 2 | groupId=com.qihoo360.argus.apm 3 | artifactId=apm-gradle 4 | version=0.0.1 5 | username= 6 | password= 7 | 8 | -------------------------------------------------------------------------------- /argus-apm-gradle/gradle.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm-gradle/gradle.properties -------------------------------------------------------------------------------- /argus-apm-gradle/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm-gradle/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /argus-apm-gradle/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2005-2017 Qihoo 360 Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | # use this file except in compliance with the License. You may obtain a copy of 6 | # the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed To in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations under 14 | # the License. 15 | # 16 | 17 | #Mon Dec 28 10:00:20 PST 2015 18 | distributionBase=GRADLE_USER_HOME 19 | distributionPath=wrapper/dists 20 | zipStoreBase=GRADLE_USER_HOME 21 | zipStorePath=wrapper/dists 22 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 23 | -------------------------------------------------------------------------------- /argus-apm-gradle/libs/aspectjtools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm-gradle/libs/aspectjtools.jar -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/AppConstant.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | object AppConstant { 4 | /** 版本号 */ 5 | const val VER = "2.0.1.1007" 6 | 7 | /** 打印信息时候的前缀 */ 8 | const val TAG = "< argus-apm-v$VER >" 9 | 10 | /** 外部用户配置信息 */ 11 | const val USER_CONFIG = "argusApmAjxConfig" 12 | /** Transform的名字*/ 13 | const val TRANSFORM_NAME = "argus_apm_ajx" 14 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/ArgusApmConfig.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | open class ArgusApmConfig { 4 | var enabled: Boolean = true 5 | var okhttpEnabled: Boolean = true 6 | var dependencyEnabled: Boolean = true 7 | val includes = arrayListOf() 8 | val excludes = arrayListOf() 9 | val excludeJars = arrayListOf() 10 | val ajcArgs = arrayListOf() 11 | val debugDependencies = arrayListOf() 12 | val moduleDependencies = arrayListOf() 13 | 14 | /** 15 | * 用来控制AJ是否织入 16 | */ 17 | fun enabled(enable: Boolean): ArgusApmConfig { 18 | this.enabled = enable 19 | return this 20 | } 21 | 22 | /** 23 | * 用来控制是否接入okhttp相关的功能 24 | */ 25 | fun okhttpEnabled(okhttpEnable: Boolean): ArgusApmConfig { 26 | this.okhttpEnabled = okhttpEnable 27 | return this 28 | } 29 | 30 | /** 31 | * 用来控制是否需要让插件默认依赖一些ArgusAPM库 32 | */ 33 | fun dependencyEnabled(dependencyEnabled: Boolean): ArgusApmConfig { 34 | this.dependencyEnabled = dependencyEnabled 35 | return this 36 | } 37 | 38 | fun include(vararg filters: String): ArgusApmConfig { 39 | this.includes.addAll(filters) 40 | return this 41 | } 42 | 43 | fun exclude(vararg filters: String): ArgusApmConfig { 44 | this.excludes.addAll(filters) 45 | return this 46 | } 47 | 48 | fun excludeJar(vararg filters: String): ArgusApmConfig { 49 | this.excludeJars.addAll(filters) 50 | return this 51 | } 52 | 53 | fun ajcArgs(vararg ajcArgs: String): ArgusApmConfig { 54 | this.ajcArgs.addAll(ajcArgs) 55 | return this 56 | } 57 | 58 | fun debugDependencies(vararg debugDependencies: String): ArgusApmConfig { 59 | this.debugDependencies.addAll(debugDependencies) 60 | return this 61 | } 62 | 63 | fun moduleDependencies(vararg moduleDependencies: String): ArgusApmConfig { 64 | this.moduleDependencies.addAll(moduleDependencies) 65 | return this 66 | } 67 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/AspectJPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | import com.android.build.gradle.AppExtension 4 | import com.android.build.gradle.AppPlugin 5 | import com.argusapm.gradle.internal.ArgusDependencyResolutionListener 6 | import com.argusapm.gradle.internal.BuildTimeListener 7 | import com.argusapm.gradle.internal.PluginConfig 8 | import com.argusapm.gradle.internal.compatCompile 9 | import org.gradle.api.Plugin 10 | import org.gradle.api.Project 11 | 12 | internal class AspectJPlugin : Plugin { 13 | private lateinit var mProject: Project 14 | override fun apply(project: Project) { 15 | mProject = project 16 | project.extensions.create(AppConstant.USER_CONFIG, ArgusApmConfig::class.java) 17 | 18 | //公共配置初始化,方便获取公共信息 19 | PluginConfig.init(project) 20 | 21 | //自定义依赖库管理 22 | project.gradle.addListener(ArgusDependencyResolutionListener(project)) 23 | 24 | project.repositories.mavenCentral() 25 | project.compatCompile("org.aspectj:aspectjrt:1.8.9") 26 | 27 | 28 | if (project.plugins.hasPlugin(AppPlugin::class.java)) { 29 | project.gradle.addListener(BuildTimeListener()) 30 | 31 | val android = project.extensions.getByType(AppExtension::class.java) 32 | android.registerTransform(AspectJTransform(project)) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/AspectJTransform.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle 2 | 3 | import com.android.build.api.transform.QualifiedContent 4 | import com.android.build.api.transform.Transform 5 | import com.android.build.api.transform.TransformInvocation 6 | import com.android.build.gradle.internal.pipeline.TransformManager 7 | import com.android.build.gradle.internal.pipeline.TransformTask 8 | import com.google.common.collect.Sets 9 | import com.argusapm.gradle.internal.PluginConfig 10 | import com.argusapm.gradle.internal.ajc.AjcWeaverManager 11 | import com.argusapm.gradle.internal.cutter.FileFilter 12 | import com.argusapm.gradle.internal.cutter.InputSourceCutter 13 | import com.argusapm.gradle.internal.cutter.InputSourceFileStatus 14 | import com.argusapm.gradle.internal.utils.LogStatus 15 | import com.argusapm.gradle.internal.utils.outputFiles 16 | import org.gradle.api.Project 17 | 18 | internal class AspectJTransform(private val project: Project) : Transform() { 19 | override fun getName(): String { 20 | return AppConstant.TRANSFORM_NAME 21 | } 22 | 23 | override fun getInputTypes(): Set { 24 | return Sets.immutableEnumSet(QualifiedContent.DefaultContentType.CLASSES)!! 25 | } 26 | 27 | override fun isIncremental(): Boolean { 28 | return true 29 | } 30 | 31 | override fun getScopes(): MutableSet { 32 | return TransformManager.SCOPE_FULL_PROJECT 33 | } 34 | 35 | override fun transform(transformInvocation: TransformInvocation) { 36 | val transformTask = transformInvocation.context as TransformTask 37 | LogStatus.logStart(transformTask.variantName) 38 | 39 | //第一步:对输入源Class文件进行切割分组 40 | val fileFilter = FileFilter(project, transformTask.variantName) 41 | val inputSourceFileStatus = InputSourceFileStatus() 42 | InputSourceCutter(transformInvocation, fileFilter, inputSourceFileStatus).startCut() 43 | 44 | //第二步:如果含有AspectJ文件,则开启织入;否则,将输入源输出到目标目录下 45 | if (PluginConfig.argusApmConfig().enabled && fileFilter.hasAspectJFile()) { 46 | AjcWeaverManager(transformInvocation, inputSourceFileStatus).weaver() 47 | } else { 48 | outputFiles(transformInvocation) 49 | } 50 | 51 | LogStatus.logEnd(transformTask.variantName) 52 | } 53 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/ArgusDependencyResolutionListener.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.argusapm.gradle.AppConstant 4 | import org.gradle.api.Project 5 | import org.gradle.api.artifacts.DependencyResolutionListener 6 | import org.gradle.api.artifacts.ResolvableDependencies 7 | 8 | val COMPILE_CONFIGURATIONS = arrayOf("api", "compile") 9 | 10 | /** 11 | * 兼容Compile模式 12 | */ 13 | fun Project.compatCompile(depLib: Any) { 14 | COMPILE_CONFIGURATIONS.find { configurations.findByName(it) != null }?.let { 15 | dependencies.add(it, depLib) 16 | } 17 | } 18 | 19 | class ArgusDependencyResolutionListener(val project: Project) : DependencyResolutionListener { 20 | override fun beforeResolve(dependencies: ResolvableDependencies?) { 21 | if (PluginConfig.argusApmConfig().dependencyEnabled) { 22 | if (PluginConfig.argusApmConfig().debugDependencies.isEmpty() && PluginConfig.argusApmConfig().moduleDependencies.isEmpty()) { 23 | project.compatCompile("com.qihoo360.argusapm:argus-apm-main:${AppConstant.VER}") 24 | project.compatCompile("com.qihoo360.argusapm:argus-apm-aop:${AppConstant.VER}") 25 | 26 | if (PluginConfig.argusApmConfig().okhttpEnabled) { 27 | project.compatCompile("com.qihoo360.argusapm:argus-apm-okhttp:${AppConstant.VER}") 28 | } 29 | } else { 30 | //配置本地Module库,方便断点调试 31 | if (PluginConfig.argusApmConfig().moduleDependencies.isNotEmpty()) { 32 | PluginConfig.argusApmConfig().moduleDependencies.forEach { moduleLib: String -> 33 | project.compatCompile(project.project(moduleLib)) 34 | } 35 | } 36 | 37 | //发布Release版本之前,可以使用Debug库测试 38 | if (PluginConfig.argusApmConfig().debugDependencies.isNotEmpty()) { 39 | project.repositories.mavenLocal() 40 | //方便在测试的时候使用,不再需要单独的Gradle发版本 41 | PluginConfig.argusApmConfig().debugDependencies.forEach { debugLib: String -> 42 | project.compatCompile(debugLib) 43 | } 44 | } 45 | } 46 | } 47 | project.gradle.removeListener(this) 48 | } 49 | 50 | override fun afterResolve(dependencies: ResolvableDependencies?) { 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/AspectJClassVisitor.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import org.objectweb.asm.AnnotationVisitor 4 | import org.objectweb.asm.ClassVisitor 5 | import org.objectweb.asm.ClassWriter 6 | import org.objectweb.asm.Opcodes 7 | 8 | class AspectJClassVisitor(classWriter: ClassWriter) : ClassVisitor(Opcodes.ASM5, classWriter) { 9 | var isAspectClass = false 10 | 11 | override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor { 12 | isAspectClass = (desc == "Lorg/aspectj/lang/annotation/Aspect;") 13 | return super.visitAnnotation(desc, visible) 14 | } 15 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/BuildTimeListener.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.argusapm.gradle.internal.utils.log 4 | import org.gradle.BuildListener 5 | import org.gradle.BuildResult 6 | import org.gradle.api.Task 7 | import org.gradle.api.execution.TaskExecutionListener 8 | import org.gradle.api.initialization.Settings 9 | import org.gradle.api.invocation.Gradle 10 | import org.gradle.api.tasks.TaskState 11 | 12 | class BuildTimeListener : TaskExecutionListener, BuildListener { 13 | 14 | private var startTime: Long = 0L 15 | private var times = mutableListOf>() 16 | 17 | override fun buildStarted(gradle: Gradle) {} 18 | override fun settingsEvaluated(settings: Settings) {} 19 | override fun projectsLoaded(gradle: Gradle) {} 20 | override fun projectsEvaluated(gradle: Gradle) {} 21 | 22 | override fun buildFinished(result: BuildResult) { 23 | log("Task spend time:") 24 | times.filter { it.first > 50 } 25 | .forEach { log("%7sms\t%s".format(it.first, it.second)) } 26 | } 27 | 28 | override fun beforeExecute(task: Task) { 29 | startTime = System.currentTimeMillis() 30 | } 31 | 32 | override fun afterExecute(task: Task, state: TaskState) { 33 | val ms = System.currentTimeMillis() - startTime 34 | times.add(Pair(ms, task.path)) 35 | task.project.logger.warn("${task.path} spend ${ms}ms") 36 | } 37 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/FileType.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | enum class FileType { 4 | DEFAULT, 5 | /** 6 | * class file like 'xxx.class' 7 | */ 8 | CLASS, 9 | /** 10 | * java source file like 'xxx.java' 11 | */ 12 | JAVA, 13 | /** 14 | * groovy source file like 'xxx.groovy' 15 | */ 16 | GROOVY, 17 | /** 18 | * kotlin source file like 'kotlin' 19 | */ 20 | KOTLIN, 21 | /** 22 | * jar file like 'xxx.jar' 23 | */ 24 | JAR 25 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/PluginConfig.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal 2 | 3 | import com.android.build.gradle.* 4 | import com.argusapm.gradle.ArgusApmConfig 5 | import com.argusapm.gradle.internal.utils.getVariants 6 | import org.gradle.api.GradleException 7 | import org.gradle.api.Project 8 | import org.gradle.api.tasks.compile.JavaCompile 9 | import java.io.File 10 | 11 | class PluginConfig { 12 | companion object { 13 | lateinit var project: Project 14 | lateinit var encoding: String 15 | lateinit var bootClassPath: String 16 | lateinit var sourceCompatibility: String 17 | lateinit var targetCompatibility: String 18 | 19 | fun init(project: Project) { 20 | val hasAppPlugin = project.plugins.hasPlugin(AppPlugin::class.java) 21 | val hasLibPlugin = project.plugins.hasPlugin(LibraryPlugin::class.java) 22 | if (!hasAppPlugin && !hasLibPlugin) { 23 | throw GradleException("argusapm: The 'com.android.application' or 'com.android.library' plugin is required.") 24 | } 25 | 26 | Companion.project = project 27 | 28 | getVariants(project).all { variant -> 29 | val javaCompile = variant.javaCompile as JavaCompile 30 | encoding = javaCompile.options.encoding 31 | bootClassPath = getBootClasspath().joinToString(File.pathSeparator) 32 | sourceCompatibility = javaCompile.sourceCompatibility 33 | targetCompatibility = javaCompile.targetCompatibility 34 | } 35 | } 36 | 37 | private fun getBootClasspath(): List { 38 | val hasAppPlugin = project.plugins.hasPlugin(AppPlugin::class.java) 39 | val plugin = project.plugins.getPlugin(if (hasAppPlugin) { 40 | AppPlugin::class.java 41 | } else { 42 | LibraryPlugin::class.java 43 | }) 44 | val extAndroid = if (hasAppPlugin) { 45 | project.extensions.getByType(AppExtension::class.java) 46 | } else { 47 | project.extensions.getByType(LibraryExtension::class.java) 48 | } 49 | return extAndroid.bootClasspath 50 | ?: plugin::class.java.getMethod("getRuntimeJarList").invoke(plugin) as List 51 | } 52 | 53 | fun argusApmConfig(): ArgusApmConfig { 54 | return project.extensions.getByType(ArgusApmConfig::class.java) 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/concurrent/ITask.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.concurrent 2 | 3 | import java.util.concurrent.Callable 4 | 5 | interface ITask : Callable -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/concurrent/ThreadPool.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.concurrent 2 | 3 | import java.util.concurrent.Executors 4 | 5 | class ThreadPool { 6 | private val executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() + 1) 7 | val taskList = arrayListOf() 8 | 9 | fun addTask(task: ITask) { 10 | taskList.add(task) 11 | } 12 | 13 | fun startWork() { 14 | executorService.invokeAll(taskList) 15 | taskList.clear() 16 | } 17 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/cutter/InputSourceFileStatus.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.cutter 2 | 3 | class InputSourceFileStatus { 4 | var isAspectChanged = false 5 | var isIncludeFileChanged = false 6 | var isExcludeFileChanged = false 7 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/utils/Logger.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.utils 2 | 3 | import com.argusapm.gradle.AppConstant 4 | 5 | fun log(info: String) { 6 | println("${AppConstant.TAG} $info") 7 | } 8 | 9 | 10 | fun logCore(info: String) { 11 | log(info) 12 | } 13 | 14 | 15 | object LogStatus { 16 | fun logStart(info: String) { 17 | println("--------------------------------------------------------------------") 18 | println(" Argus-Apm [$info] Start... ") 19 | println() 20 | } 21 | 22 | fun isIncremental(info: String) { 23 | log("now is: isIncremental [$info]") 24 | } 25 | 26 | fun cutStart() { 27 | log("cut input source start...") 28 | } 29 | 30 | fun cutEnd() { 31 | log("cut input source end...") 32 | } 33 | 34 | fun ajcJar(info: String) { 35 | log("this [$info] will be compiled by ajc") 36 | } 37 | 38 | fun weaveStart() { 39 | log("ajc weave start...") 40 | } 41 | 42 | fun logEnd(info: String) { 43 | println() 44 | println(" Argus-Apm [$info] end... ") 45 | println("--------------------------------------------------------------------") 46 | } 47 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/kotlin/com/argusapm/gradle/internal/utils/VariantUtils.kt: -------------------------------------------------------------------------------- 1 | package com.argusapm.gradle.internal.utils 2 | 3 | import com.android.build.gradle.AppExtension 4 | import com.android.build.gradle.api.ApplicationVariant 5 | import org.gradle.api.DomainObjectSet 6 | import org.gradle.api.Project 7 | 8 | fun getVariants(project: Project): DomainObjectSet { 9 | return project.extensions.getByType(AppExtension::class.java).applicationVariants 10 | } -------------------------------------------------------------------------------- /argus-apm-gradle/src/main/resources/META-INF/gradle-plugins/argusapm.properties: -------------------------------------------------------------------------------- 1 | implementation-class=com.argusapm.gradle.AspectJPlugin -------------------------------------------------------------------------------- /argus-apm/README.md: -------------------------------------------------------------------------------- 1 | > APM -------------------------------------------------------------------------------- /argus-apm/argus-apm-aop/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-aop/argus-apm-aop.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in ./sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -keep class com.argusapm.android.aop.* { 27 | *; 28 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-aop/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /argus-apm/argus-apm-aop/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/argus-apm-cloud-dummy-impl.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in ./sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -keep class com.argusapm.android.network.cloudrule.** {*;} 27 | -keep class com.argusapm.android.network.upload.CollectDataSyncUpload{*;} -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 27 5 | buildToolsVersion "27.0.3" 6 | 7 | if (!ArgusAPM_Release) { 8 | publishNonDefault true 9 | } 10 | 11 | defaultConfig { 12 | minSdkVersion 15 13 | targetSdkVersion 27 14 | versionCode 1 15 | versionName "1.0" 16 | consumerProguardFiles 'argus-apm-cloud-dummy-impl.pro' 17 | } 18 | 19 | lintOptions { 20 | abortOnError false 21 | } 22 | 23 | useLibrary 'org.apache.http.legacy' 24 | } 25 | 26 | afterEvaluate { 27 | generateReleaseBuildConfig.enabled = false 28 | generateDebugBuildConfig.enabled = false 29 | } 30 | 31 | dependencies { 32 | compile fileTree(include: ['*.jar'], dir: 'libs') 33 | if (ArgusAPM_Release) { 34 | compile project(':argus-apm-cloud') 35 | } else { 36 | releaseCompile project(path: ':argus-apm-cloud', configuration: 'release') 37 | debugCompile project(path: ':argus-apm-cloud', configuration: 'debug') 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -keep class com.argusapm.android.network.cloudrule.** {*;} 23 | -keep class com.argusapm.android.network.upload.CollectDataSyncUpload{*;} 24 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/src/main/assets/argus_apm_sdk_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "anr_filter":"com.apm.application,com.apm", 3 | "clean_exp":2, 4 | "clean_interval":7200000, 5 | "cloud_interval":3600000, 6 | "control_activity":0, 7 | "debug":true, 8 | "file_data_dirs":"shared_prefs", 9 | "func_control": 10 | { 11 | "activity_first_min_time":300, 12 | "activity_lifecycle_min_time":100, 13 | "block_min_time":4500, 14 | "file_dir_depth":3, 15 | "io_min_time":3000, 16 | "memory_delay_time":10000, 17 | "min_file_size":51200, 18 | "onreceive_min_time":2000, 19 | "thread_min_time":4000 20 | }, 21 | "g_core": 22 | { 23 | "activity":true, 24 | "anr":true, 25 | "appstart":true, 26 | "battery":true, 27 | "block":true, 28 | "cpu":true, 29 | "exp":2158934400000, 30 | "fileinfo":true, 31 | "fps":true, 32 | "func":true, 33 | "io":true, 34 | "memory":true, 35 | "monitor":true, 36 | "net":true, 37 | "processinfo":true, 38 | "sfps":true, 39 | "webview":true, 40 | "watchdog":true, 41 | "threadcnt":true 42 | }, 43 | "once_max_count":30, 44 | "pause_interval":14400000, 45 | "random_control_time":300000, 46 | "timestamp":1540779526000, 47 | "upload_interval":14400000 48 | } 49 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/src/main/java/com/argusapm/android/network/cloudrule/RuleSyncRequest.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network.cloudrule; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | import android.util.Log; 6 | 7 | import com.argusapm.android.network.IRuleRequest; 8 | 9 | import java.io.BufferedReader; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | 13 | import static com.argusapm.android.network.DebugConfig.TAG_O; 14 | 15 | /** 16 | * 云控同步请求 17 | * 18 | * @author ArgusAPM Team 19 | */ 20 | public class RuleSyncRequest implements IRuleRequest { 21 | 22 | @Override 23 | public String request(Context context, String apmId, String apmVer, String appName, String appVer) { 24 | // TODO: 模拟网络请求,直接返回请求成功的数据;如果有自己的云规则服务器,可以自行实现网络请求的逻辑 25 | return getCloudFileContent(context, "argus_apm_sdk_config.json"); 26 | } 27 | 28 | //读取assets目录下的云规则文件 29 | private String getCloudFileContent(Context context, String fileName) { 30 | StringBuilder stringBuilder = new StringBuilder(); 31 | try { 32 | AssetManager assetManager = context.getAssets(); 33 | BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open(fileName))); 34 | String line; 35 | while ((line = bf.readLine()) != null) { 36 | stringBuilder.append(line); 37 | } 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | Log.d(TAG_O, "cloudrule response " + 0); 42 | 43 | return stringBuilder.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/src/main/java/com/argusapm/android/network/upload/CollectDataSyncUpload.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network.upload; 2 | 3 | import android.content.Context; 4 | 5 | import com.argusapm.android.network.IUpload; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * 采集的数据上传的接口 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class CollectDataSyncUpload implements IUpload { 15 | 16 | @Override 17 | public boolean upload(Context context, String apmId, Map data) { 18 | // TODO: 模拟上传成功,直接返回true,如果需要上传至自己的服务器,请自行实现 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud-dummy-impl/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | network-impl 3 | 4 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/argus-apm-cloud-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in ./sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -keep class com.apm.mobile.network.cloudrule.** {*;} 27 | -keep class com.apm.mobile.network.upload.IUpload{*;} -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 27 5 | buildToolsVersion "27.0.3" 6 | 7 | if (!ArgusAPM_Release) { 8 | publishNonDefault true 9 | } 10 | 11 | defaultConfig { 12 | minSdkVersion 15 13 | targetSdkVersion 27 14 | versionCode 1 15 | versionName "1.0" 16 | consumerProguardFiles 'argus-apm-cloud-rules.pro' 17 | } 18 | 19 | lintOptions { 20 | abortOnError false 21 | } 22 | } 23 | 24 | afterEvaluate { 25 | generateReleaseBuildConfig.enabled = false 26 | generateDebugBuildConfig.enabled = false 27 | } 28 | 29 | dependencies { 30 | compile fileTree(include: ['*.jar'], dir: 'libs') 31 | } 32 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -keep class com.argusapm.android.network.cloudrule.** {*;} 23 | -keep class com.argusapm.android.network.IUpload{*;} -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/src/main/java/com/argusapm/android/network/DebugConfig.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network; 2 | 3 | /** 4 | * cloud model调试配置 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class DebugConfig { 9 | public static boolean DEBUG = false; 10 | /** 11 | * apm日志输出TAG 12 | */ 13 | public static String TAG = "apm_debug"; 14 | 15 | /** 16 | * apm对外输出的日志TAG 17 | */ 18 | public static String TAG_O = "argus_apm"; 19 | } 20 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/src/main/java/com/argusapm/android/network/IRuleRequest.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * 云规则网络请求接口 7 | * 8 | * @author ArgusAPM Team 9 | */ 10 | public interface IRuleRequest { 11 | /** 12 | * 请求apm配置数据 13 | * @param context 14 | * @param apmId 15 | * @param apmVer 16 | * @param appName 17 | * @param appVer 18 | * @return 19 | */ 20 | String request(Context context, String apmId, String apmVer, String appName, String appVer); 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/src/main/java/com/argusapm/android/network/IUpload.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * 上传数据采集结果的接口 9 | * 10 | * @author ArgusAPM Team 11 | */ 12 | public interface IUpload { 13 | /** 14 | * 上传采集到的数据 15 | * 16 | * @param apmId 17 | * @param data 18 | * @return 19 | */ 20 | boolean upload(Context context, String apmId, Map data); 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-cloud/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | network 3 | 4 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply from: "sdk_utils.gradle" 3 | 4 | android { 5 | compileSdkVersion 27 6 | buildToolsVersion "27.0.3" 7 | 8 | if (!ArgusAPM_Release) { 9 | publishNonDefault true 10 | } 11 | 12 | defaultConfig { 13 | minSdkVersion 10 14 | targetSdkVersion 27 15 | 16 | // 改参数一般用来调试数据库,数据库生成在sdcard方便调试 17 | buildConfigField "boolean", "DB_IN_SDCARD", "false" 18 | // SDK的版本号 19 | buildConfigField "String", "VERSION", "\"${APMSDK_VERSION}\"" 20 | // 是否是Debug 21 | buildConfigField "boolean", "IS_DEBUG", "${APMSDK_DEBUG}" 22 | // SDK的build号 23 | // 不同版本间,需要更新build号 24 | buildConfigField "String", "BUILD", "\"${APMSDK_BUILD}\"" 25 | } 26 | 27 | buildTypes { 28 | 29 | debug { 30 | minifyEnabled false 31 | zipAlignEnabled false 32 | shrinkResources false 33 | consumerProguardFiles 'argus-apm-main.pro' 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'argus-apm-main.pro' 35 | } 36 | 37 | release { 38 | minifyEnabled true 39 | zipAlignEnabled true 40 | shrinkResources true 41 | consumerProguardFiles 'argus-apm-main.pro' 42 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'argus-apm-main.pro' 43 | } 44 | } 45 | 46 | lintOptions { 47 | abortOnError false 48 | } 49 | 50 | compileOptions { 51 | sourceCompatibility JavaVersion.VERSION_1_7 52 | targetCompatibility JavaVersion.VERSION_1_7 53 | } 54 | 55 | useLibrary 'org.apache.http.legacy' 56 | } 57 | 58 | dependencies { 59 | compile fileTree(include: ['*.jar'], dir: 'libs') 60 | provided 'org.aspectj:aspectjrt:1.8.9' 61 | provided 'org.aspectj:aspectjtools:1.8.9' 62 | //下面的两行是方便在Debug调试时使用,发布Release包时需要将下面的两行注释掉,并执行copyNewDependentLibs任务 63 | if (!ArgusAPM_Release) { 64 | releaseCompile project(path: ':argus-apm-cloud-dummy-impl', configuration: 'release') 65 | debugCompile project(path: ':argus-apm-cloud-dummy-impl', configuration: 'debug') 66 | } 67 | } 68 | 69 | apply from: "bintray.gradle" -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/libs/argus-apm-cloud-dummy-impl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm/argus-apm-main/libs/argus-apm-cloud-dummy-impl.jar -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/libs/argus-apm-cloud.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm/argus-apm-main/libs/argus-apm-cloud.jar -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/sdk_utils.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | // debug版带日志 3 | APMSDK_DEBUG = false 4 | APMSDK_VERSION = "2.0.1" 5 | APMSDK_BUILD = "1006" 6 | 7 | getDirSuffix = this.&getDirSuffix 8 | APM_TASKS_GROUP = "argus" 9 | } 10 | 11 | String getTime() { 12 | Calendar calendar = Calendar.getInstance(); 13 | StringBuilder sbuilder = new StringBuilder(); 14 | sbuilder.append(calendar.get(Calendar.YEAR) + "-"); 15 | sbuilder.append(calendar.get(Calendar.MONTH) + 1 + "-"); 16 | sbuilder.append(calendar.get(Calendar.DAY_OF_MONTH) + "-"); 17 | sbuilder.append(calendar.get(Calendar.HOUR_OF_DAY) + "-"); 18 | sbuilder.append(calendar.get(Calendar.MINUTE) + "-"); 19 | sbuilder.append(calendar.get(Calendar.MILLISECOND)); 20 | return sbuilder.toString(); 21 | } 22 | 23 | String getDirSuffix() { 24 | String suffix = APMSDK_VERSION + "." + APMSDK_BUILD + "-[" + getTime() + "]"; 25 | return suffix.replaceAll("\"", ""); 26 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/Env.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android; 2 | 3 | /** 4 | * APM全局配置文件 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class Env { 9 | public static final boolean DEBUG = BuildConfig.IS_DEBUG; 10 | 11 | public static final String VERSION = BuildConfig.VERSION; 12 | public static final String BUILD = BuildConfig.BUILD; 13 | 14 | public static final String getVersionName() { 15 | return VERSION + "." + BUILD; 16 | } 17 | 18 | /** 19 | * apm日志输出TAG 20 | */ 21 | public static final String TAG = "apm_debug"; 22 | 23 | /** 24 | * apm对外输出的日志TAG 25 | */ 26 | public static final String TAG_O = "argus_apm"; 27 | 28 | /** 29 | * 是否将数据库生成到sdcard方便调试 30 | */ 31 | public static final boolean DB_IN_SDCARD = BuildConfig.DB_IN_SDCARD; 32 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/aop/IActivityHelper.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.aop; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | /** 7 | * @author ArgusAPM Team 8 | */ 9 | public interface IActivityHelper { 10 | // activity的生命周期处理 11 | void invoke(Activity activity, long startTime, String lifeCycle, Object... args); 12 | 13 | // application的onCreate处理 14 | void applicationOnCreate(Context context); 15 | 16 | // application的attachBaseContext处理 17 | void applicationAttachBaseContext(Context context); 18 | 19 | // 扩展用 20 | Object parse(Object... args); 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/aop/IAopTraceHelper.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.aop; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public interface IAopTraceHelper { 7 | void dispatch(long startTime, 8 | String kind, 9 | String sign, 10 | Object[] args, 11 | Object target, 12 | Object thiz, 13 | String location, 14 | String staticPartStr, 15 | String methodName, 16 | Object result 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/api/ExtraDataType.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.api; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public class ExtraDataType { 7 | public static final int TYPE_GET_PLUGIN_NAME = 0; 8 | public static final int TYPE_GET_PLUGIN_VERSION = 1; 9 | public static final int TYPE_GET_MAIN_VERSION = 2; 10 | public static final int TYPE_RECV_V5_UPDATE = 3; 11 | } 12 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/api/IExtraDataCallback.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.api; 2 | 3 | /** 4 | * 该接口用于sdk读取外部数据 5 | * 第一个参数(int):代表类型 6 | * 其余参数,根据类型确定 7 | * 8 | * @author ArgusAPM Team 9 | */ 10 | public interface IExtraDataCallback { 11 | Object parse(Object... args); 12 | } 13 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/cloudconfig/Constant.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.cloudconfig; 2 | 3 | /** 4 | * 云控逻辑常量配置类 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class Constant { 9 | // 配置请求的最小时间间隔 10 | public static final long INTERVAL = 1 * 60 * 60 * 1000; 11 | public static final long APP_START_CLOUD_MAX_DELAY_TIME = 10 * 1000;//APP(进程)启动候,云控请求最大延迟 12 | public static final long CLOUD_MIN_INTERVAL = 5 * 60 * 1000; //云规则请求的最小时间间隔 13 | public static final String CLOUD_RULE_UPDATE_ACTION = "com.apm.mobile.action.cloud.rule.update"; 14 | } 15 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/cloudconfig/data/ArgusApmConfigCore.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.cloudconfig.data; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | 7 | /** 8 | * 云控数据g_core段 9 | * 10 | * @author ArgusAPM Team 11 | */ 12 | public class ArgusApmConfigCore { 13 | private long exp = Long.MAX_VALUE; 14 | private int flags = 0;// 采集默认为全关 15 | 16 | public long getExp() { 17 | return exp; 18 | } 19 | 20 | public void setExp(long exp) { 21 | this.exp = exp; 22 | } 23 | 24 | public void setEnabled(int flag) { 25 | flags |= flag; 26 | } 27 | 28 | public void setDisabled(int flag) { 29 | flags &= (~flag); 30 | } 31 | 32 | public boolean isEnabled(String task) { 33 | if (TextUtils.isEmpty(task)) { 34 | return false; 35 | } 36 | Integer obj = ApmTask.getTaskMap().get(task); 37 | if (obj == null) { 38 | return false; 39 | } 40 | int flag = obj.intValue(); 41 | boolean switchState = (flags & flag) == flag; 42 | long curTime = System.currentTimeMillis(); 43 | boolean isValidTime = curTime < exp; 44 | return switchState && isValidTime; 45 | } 46 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/IInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core; 2 | 3 | import android.content.ContentValues; 4 | 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 通用基本数据接口 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public interface IInfo extends Serializable { 16 | // 目前是数据库自增字段 17 | int getId(); 18 | 19 | JSONObject toJson() throws JSONException; 20 | 21 | void parserJsonStr(String json) throws JSONException; 22 | 23 | void parserJson(JSONObject json) throws JSONException; 24 | 25 | ContentValues toContentValues(); 26 | 27 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/ReceiverManager.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | 8 | import com.argusapm.android.utils.AsyncThreadTask; 9 | import com.argusapm.android.utils.PreferenceUtils; 10 | 11 | /** 12 | * argus apm receiver管理类 13 | * 14 | * @author ArgusAPM Team 15 | */ 16 | public class ReceiverManager { 17 | public static final int UPDATE_READ_CONFIG_INTERVAL = 2 * 60 * 60 * 1000; 18 | private ScreenReceiver screenReceiver; 19 | 20 | public void init(Context context) { 21 | if (context == null) { 22 | return; 23 | } 24 | if (screenReceiver == null) { 25 | screenReceiver = new ScreenReceiver(); 26 | } 27 | context.registerReceiver(screenReceiver, getIntentFilter()); 28 | } 29 | 30 | private IntentFilter getIntentFilter() { 31 | IntentFilter filter = new IntentFilter(); 32 | filter.addAction(Intent.ACTION_SCREEN_OFF); 33 | filter.addAction(Intent.ACTION_SCREEN_ON); 34 | return filter; 35 | } 36 | 37 | //定时任务 38 | private Runnable runnable = new Runnable() { 39 | @Override 40 | public void run() { 41 | Manager.getInstance().reload(); 42 | if (Manager.getContext() == null) { 43 | return; 44 | } 45 | PreferenceUtils.setLong(Manager.getContext(), PreferenceUtils.SP_KEY_UPDATE_READ_CONFIG_TIME, System.currentTimeMillis()); 46 | } 47 | }; 48 | 49 | class ScreenReceiver extends BroadcastReceiver { 50 | @Override 51 | public void onReceive(Context context, Intent intent) { 52 | if (Manager.getContext() == null) { 53 | return; 54 | } 55 | long lastTime = PreferenceUtils.getLong(Manager.getContext(), PreferenceUtils.SP_KEY_UPDATE_READ_CONFIG_TIME, 0); 56 | long cur = System.currentTimeMillis(); 57 | if ((cur - lastTime) < UPDATE_READ_CONFIG_INTERVAL) { 58 | return; 59 | } 60 | String action = intent.getAction(); 61 | if (Intent.ACTION_SCREEN_OFF.equals(action)) { 62 | 63 | } else if (Intent.ACTION_SCREEN_ON.equals(action)) { 64 | AsyncThreadTask.executeDelayedToUI(runnable, 5000 + (int) (Math.round(Math.random() * 1000))); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/StorageConfig.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core; 2 | 3 | /** 4 | * 存储相关配置 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class StorageConfig { 9 | public static final String CONTENT_PATH_PREFIX = "content://"; 10 | public static final String AUTHORITY_SUFFIX = "apm.storage"; 11 | public static final String DB_NAME = "apm.db"; //数据库名称 12 | public static final int DB_VERSION = 14; //数据库版本号,字段新增或改变后,必须升级此版本号 13 | 14 | public static final int SAVE_DB_INTERVAL = 15 * 1000;// 写入数据库最短时间间隔,防止频繁IO 15 | public static final int SAVE_DB_MAX_COUNT = 100;// 写入数据库最大缓存条数 16 | 17 | 18 | /*****************数据清理相关配置************************/ 19 | public static final long DATA_CLEAR_INTERVAL_TIME = 2 * 60 * 60 * 1000; // 两小时执行一次即可 20 | public static final long DATA_CLEAR_INTERVAL_MIN_TIME = 10 * 60 * 1000; // 触发清理的最短时间是10分钟 21 | public static final int DATA_OVER_DAY = 2; //日志过期时间(天) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/AH.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.text.TextUtils; 6 | 7 | import com.argusapm.android.Env; 8 | import com.argusapm.android.api.ApmTask; 9 | import com.argusapm.android.core.Manager; 10 | import com.argusapm.android.utils.LogX; 11 | 12 | /** 13 | * 用于Activity的AOP方案 14 | * 15 | * @author ArgusAPM Team 16 | */ 17 | public class AH { 18 | public static final String SUB_TAG = "traceactivity"; 19 | 20 | public static void invoke(Activity activity, long startTime, String lifeCycle, Object... extars) { 21 | boolean isRunning = isActivityTaskRunning(); 22 | if (Env.DEBUG) { 23 | LogX.d(Env.TAG, SUB_TAG, lifeCycle + " isRunning : " + isRunning); 24 | } 25 | if (!isRunning) { 26 | return; 27 | } 28 | 29 | if (TextUtils.equals(lifeCycle, ActivityInfo.TYPE_STR_ONCREATE)) { 30 | ActivityCore.onCreateInfo(activity, startTime); 31 | } else { 32 | int lc = ActivityInfo.ofLifeCycleString(lifeCycle); 33 | if (lc <= ActivityInfo.TYPE_UNKNOWN || lc > ActivityInfo.TYPE_DESTROY) { 34 | return; 35 | } 36 | ActivityCore.saveActivityInfo(activity, ActivityInfo.HOT_START, System.currentTimeMillis() - startTime, lc); 37 | } 38 | } 39 | 40 | public static void applicationAttachBaseContext(Context context) { 41 | ActivityCore.appAttachTime = System.currentTimeMillis(); 42 | if (Env.DEBUG) { 43 | LogX.d(Env.TAG, SUB_TAG, "applicationAttachBaseContext time : " + ActivityCore.appAttachTime); 44 | } 45 | } 46 | 47 | public static void applicationOnCreate(Context context) { 48 | if (Env.DEBUG) { 49 | LogX.d(Env.TAG, SUB_TAG, "applicationOnCreate"); 50 | } 51 | 52 | } 53 | 54 | public static boolean isActivityTaskRunning() { 55 | boolean useInstrumation = Manager.getInstance().getConfig().isEnabled(ApmTask.FLAG_COLLECT_ACTIVITY_AOP); 56 | return useInstrumation && ActivityCore.isActivityTaskRunning(); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/ActivityCounter.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 目前用于判断当前app是否在前台 8 | * 9 | * @author ArgusAPM Team 10 | */ 11 | public class ActivityCounter { 12 | 13 | private List mListener = new ArrayList(); 14 | 15 | private int mCounter = 0; 16 | private String mCurActivity = ""; 17 | 18 | /** 19 | * Activity onResume 调用 20 | * 记录当前显示的activity 21 | */ 22 | public void inc(String activityName) { 23 | mCurActivity = activityName; 24 | mCounter++; 25 | 26 | if (isVisible()) { 27 | dispacthOnVisible(); 28 | } 29 | } 30 | 31 | /** 32 | * Activity onPause 调用 33 | */ 34 | public void dec() { 35 | mCurActivity = ""; 36 | mCounter--; 37 | } 38 | 39 | /** 40 | * 判断当前是否有activity在前台 41 | * 42 | * @return 43 | */ 44 | public boolean isVisible() { 45 | return mCounter > 0; 46 | } 47 | 48 | /** 49 | * 获取当前显示的activity的名字 50 | * 51 | * @return 52 | */ 53 | public String getCurActivity() { 54 | return mCurActivity; 55 | } 56 | 57 | public void reset() { 58 | mCounter = 0; 59 | } 60 | 61 | public void register(UIListener listener) { 62 | if (listener == null) { 63 | return; 64 | } 65 | 66 | if (mListener.contains(listener)) { 67 | return; 68 | } 69 | 70 | mListener.add(listener); 71 | 72 | } 73 | 74 | public void unRegister(UIListener listener) { 75 | if (listener == null) { 76 | return; 77 | } 78 | if (mListener.contains(listener)) { 79 | mListener.remove(listener); 80 | } 81 | } 82 | 83 | private void dispacthOnVisible() { 84 | if (mListener.isEmpty()) { 85 | return; 86 | } 87 | for (UIListener l : mListener) { 88 | l.onVisible(); 89 | } 90 | } 91 | 92 | public interface UIListener { 93 | void onVisible(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/ActivityHelper.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import com.argusapm.android.aop.IActivityHelper; 7 | 8 | /** 9 | * 用于AOP 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class ActivityHelper implements IActivityHelper { 14 | @Override 15 | public void applicationAttachBaseContext(Context context) { 16 | AH.applicationAttachBaseContext(context); 17 | } 18 | 19 | 20 | @Override 21 | public void invoke(Activity activity, long startTime, String lifeCycle, Object... args) { 22 | AH.invoke(activity, startTime, lifeCycle, args); 23 | } 24 | 25 | @Override 26 | public void applicationOnCreate(Context context) { 27 | AH.applicationOnCreate(context); 28 | } 29 | 30 | @Override 31 | public Object parse(Object... args) { 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/ActivityTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * Activity表 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class ActivityTable implements ITable { 15 | @Override 16 | public String createSql() { 17 | return TextUtils.concat(DbHelper.CREATE_TABLE_PREFIX + getTableName(), 18 | "(", ActivityInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 19 | ActivityInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 20 | ActivityInfo.KEY_NAME, DbHelper.DATA_TYPE_TEXT, 21 | ActivityInfo.KEY_START_TYPE, DbHelper.DATA_TYPE_INTEGER, 22 | ActivityInfo.KEY_TIME, DbHelper.DATA_TYPE_INTEGER, 23 | ActivityInfo.KEY_LIFE_CYCLE, DbHelper.DATA_TYPE_INTEGER, 24 | ActivityInfo.KEY_APP_NAME, DbHelper.DATA_TYPE_TEXT, 25 | ActivityInfo.KEY_APP_VER, DbHelper.DATA_TYPE_TEXT, 26 | ActivityInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 27 | ActivityInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 28 | ActivityInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 29 | ).toString(); 30 | } 31 | 32 | @Override 33 | public String getTableName() { 34 | return ApmTask.TASK_ACTIVITY; 35 | } 36 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/ActivityTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.Manager; 5 | import com.argusapm.android.core.storage.IStorage; 6 | import com.argusapm.android.core.tasks.BaseTask; 7 | import com.argusapm.android.utils.LogX; 8 | 9 | import static com.argusapm.android.Env.DEBUG; 10 | import static com.argusapm.android.Env.TAG; 11 | 12 | /** 13 | * @author ArgusAPM Team 14 | */ 15 | public class ActivityTask extends BaseTask { 16 | 17 | @Override 18 | protected IStorage getStorage() { 19 | return new ActivityStorage(); 20 | } 21 | 22 | @Override 23 | public String getTaskName() { 24 | return ApmTask.TASK_ACTIVITY; 25 | } 26 | 27 | @Override 28 | public void start() { 29 | super.start(); 30 | if (Manager.getInstance().getConfig().isEnabled(ApmTask.FLAG_COLLECT_ACTIVITY_INSTRUMENTATION) && !InstrumentationHooker.isHookSucceed()) {//hook失败 31 | if (DEBUG) { 32 | LogX.d(TAG, "ActivityTask", "canWork hook : hook失败"); 33 | } 34 | mIsCanWork = false; 35 | } 36 | } 37 | 38 | @Override 39 | public boolean isCanWork() { 40 | return mIsCanWork; 41 | } 42 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/activity/InstrumentationHooker.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.activity; 2 | 3 | import android.app.Instrumentation; 4 | 5 | import com.argusapm.android.utils.LogX; 6 | 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.lang.reflect.Method; 10 | 11 | import static com.argusapm.android.Env.DEBUG; 12 | import static com.argusapm.android.Env.TAG; 13 | 14 | /** 15 | * Instrumentation Hook类 16 | * 17 | * @author ArgusAPM Team 18 | */ 19 | public class InstrumentationHooker { 20 | private static boolean isHookSucceed = false;//是否已经hook成功 21 | 22 | public static void doHook() { 23 | try { 24 | hookInstrumentation(); 25 | isHookSucceed = true; 26 | } catch (Exception e) { 27 | if (DEBUG) { 28 | LogX.e(TAG, "InstrumentationHooker", e.toString()); 29 | } 30 | } 31 | } 32 | 33 | static boolean isHookSucceed() { 34 | return isHookSucceed; 35 | } 36 | 37 | private static void hookInstrumentation() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { 38 | Class c = Class.forName("android.app.ActivityThread"); 39 | Method currentActivityThread = c.getDeclaredMethod("currentActivityThread"); 40 | boolean acc = currentActivityThread.isAccessible(); 41 | if (!acc) { 42 | currentActivityThread.setAccessible(true); 43 | } 44 | Object o = currentActivityThread.invoke(null); 45 | if (!acc) { 46 | currentActivityThread.setAccessible(acc); 47 | } 48 | Field f = c.getDeclaredField("mInstrumentation"); 49 | acc = f.isAccessible(); 50 | if (!acc) { 51 | f.setAccessible(true); 52 | } 53 | Instrumentation currentInstrumentation = (Instrumentation) f.get(o); 54 | Instrumentation ins = new ApmInstrumentation(currentInstrumentation); 55 | f.set(o, ins); 56 | if (!acc) { 57 | f.setAccessible(acc); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/anr/AnrFileTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.anr; 2 | 3 | import android.content.Context; 4 | import android.os.FileObserver; 5 | import android.text.TextUtils; 6 | 7 | import com.argusapm.android.Env; 8 | import com.argusapm.android.utils.LogX; 9 | 10 | /** 11 | * anr数据解析:采用FileObserver的方式 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public class AnrFileTask extends AnrTask { 16 | public static final String SUB_TAG = "AnrFileTask"; 17 | 18 | public AnrFileTask(Context c) { 19 | super(c); 20 | } 21 | 22 | FileObserver fileObserver = new FileObserver(ANR_DIR, FileObserver.CLOSE_WRITE) { 23 | @Override 24 | public void onEvent(int event, String simplePath) { 25 | if (Env.DEBUG) { 26 | LogX.d(Env.TAG, SUB_TAG, "anr happen : event " + event + " | path " + simplePath); 27 | } 28 | if (TextUtils.isEmpty(simplePath)) { 29 | return; 30 | } 31 | String path = ANR_DIR + simplePath; 32 | 33 | if (!path.contains("trace")) { 34 | if (Env.DEBUG) { 35 | LogX.d(Env.TAG, SUB_TAG, path + " is not anr file"); 36 | } 37 | return; 38 | } 39 | handle(path); 40 | } 41 | }; 42 | 43 | @Override 44 | public void start() { 45 | super.start(); 46 | if (Env.DEBUG) { 47 | LogX.d(Env.TAG, SUB_TAG, "startWatching"); 48 | } 49 | fileObserver.startWatching(); 50 | } 51 | 52 | @Override 53 | public void stop() { 54 | super.stop(); 55 | if (Env.DEBUG) { 56 | LogX.d(Env.TAG, SUB_TAG, "stopWatching"); 57 | } 58 | fileObserver.stopWatching(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/anr/AnrInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.anr; 2 | 3 | import com.argusapm.android.core.BaseInfo; 4 | 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | 8 | /** 9 | * ANR信息类型 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class AnrInfo extends BaseInfo { 14 | public static final String KEY_PRO_NAME = "P"; 15 | public static final String KEY_PRO_ID = "pid"; 16 | public static final String KEY_CONTENT = "c"; 17 | public static final String KEY_TIME = "t"; 18 | private String proName; 19 | private long time; 20 | private String anrContent; 21 | private long proId; 22 | 23 | public String getProName() { 24 | return proName; 25 | } 26 | 27 | public void setProName(String proName) { 28 | this.proName = proName; 29 | } 30 | 31 | public long getTime() { 32 | return time; 33 | } 34 | 35 | public void setTime(long time) { 36 | this.time = time; 37 | } 38 | 39 | public String getAnrContent() { 40 | return anrContent; 41 | } 42 | 43 | public void setAnrContent(String anrContent) { 44 | this.anrContent = anrContent; 45 | } 46 | 47 | public long getProId() { 48 | return proId; 49 | } 50 | 51 | public void setProId(long proId) { 52 | this.proId = proId; 53 | } 54 | 55 | @Override 56 | public JSONObject toJson() throws JSONException { 57 | JSONObject ori = super.toJson() 58 | .put(KEY_PRO_NAME, proName) 59 | .put(KEY_CONTENT, anrContent) 60 | .put(KEY_PRO_ID, proId) 61 | .put(KEY_TIME, time); 62 | return ori; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/appstart/AppStartInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.appstart; 2 | 3 | import android.content.ContentValues; 4 | 5 | import com.argusapm.android.core.BaseInfo; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | /** 11 | * App启动时间Info 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public class AppStartInfo extends BaseInfo { 16 | public static String KEY_START_TIME = "st"; 17 | 18 | private int mStartTime; 19 | 20 | public AppStartInfo(int id, int startTime) { 21 | this(id, 0, startTime); 22 | } 23 | 24 | public AppStartInfo(int id, long recordTime, int startTime) { 25 | mId = id; 26 | mStartTime = startTime; 27 | this.recordTime = recordTime; 28 | } 29 | 30 | 31 | public AppStartInfo(int startTime) { 32 | this(-1, startTime); 33 | } 34 | 35 | @Override 36 | public JSONObject toJson() throws JSONException { 37 | JSONObject ori = super.toJson() 38 | .put(KEY_START_TIME, mStartTime); 39 | return ori; 40 | } 41 | 42 | public int getStartTime() { 43 | return mStartTime; 44 | } 45 | 46 | @Override 47 | public void parserJsonStr(String json) throws JSONException { 48 | parserJson(new JSONObject(json)); 49 | } 50 | 51 | @Override 52 | public void parserJson(JSONObject json) throws JSONException { 53 | this.mStartTime = json.getInt(KEY_START_TIME); 54 | } 55 | 56 | @Override 57 | public ContentValues toContentValues() { 58 | ContentValues values = new ContentValues(); 59 | values.put(KEY_START_TIME, mStartTime); 60 | return values; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | String value; 66 | try { 67 | value = toJson().toString(); 68 | } catch (Exception e) { 69 | value = super.toString(); 70 | } 71 | return value; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/appstart/AppStartStorage.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.appstart; 2 | 3 | import android.database.Cursor; 4 | import android.net.Uri; 5 | 6 | import com.argusapm.android.api.ApmTask; 7 | import com.argusapm.android.core.IInfo; 8 | import com.argusapm.android.core.Manager; 9 | import com.argusapm.android.core.job.fileinfo.FileInfo; 10 | import com.argusapm.android.core.job.memory.MemoryInfo; 11 | import com.argusapm.android.core.job.memory.MemoryTable; 12 | import com.argusapm.android.core.storage.TableStorage; 13 | import com.argusapm.android.utils.IOStreamUtils; 14 | import com.argusapm.android.utils.LogX; 15 | 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | 19 | import static com.argusapm.android.Env.DEBUG; 20 | import static com.argusapm.android.Env.TAG; 21 | 22 | /** 23 | * AppStart存储类 24 | * 25 | * @author ArgusAPM Team 26 | */ 27 | public class AppStartStorage extends TableStorage { 28 | private final String SUB_TAG = "AppStartStorage"; 29 | 30 | @Override 31 | public String getName() { 32 | return ApmTask.TASK_APP_START; 33 | } 34 | 35 | @Override 36 | public List readDb(String selection) { 37 | List infos = new LinkedList(); 38 | Cursor cursor = null; 39 | try { 40 | cursor = Manager.getInstance().getConfig().appContext.getContentResolver() 41 | .query(getTableUri(), null, selection, null, null); 42 | if (null == cursor || !cursor.moveToFirst()) { 43 | IOStreamUtils.closeQuietly(cursor); 44 | return infos; 45 | } 46 | int indexId = cursor.getColumnIndex(AppStartInfo.KEY_ID_RECORD); 47 | int indexStartTime = cursor.getColumnIndex(AppStartInfo.KEY_START_TIME); 48 | int indexTimeRecord = cursor.getColumnIndex(AppStartInfo.KEY_TIME_RECORD); 49 | do { 50 | infos.add(new AppStartInfo( 51 | cursor.getInt(indexId), 52 | cursor.getLong(indexTimeRecord), 53 | cursor.getInt(indexStartTime) 54 | )); 55 | } while (cursor.moveToNext()); 56 | } catch (Exception e) { 57 | if (DEBUG) { 58 | LogX.e(TAG, SUB_TAG, getName() + "; " + e.toString()); 59 | } 60 | } finally { 61 | IOStreamUtils.closeQuietly(cursor); 62 | } 63 | return infos; 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/appstart/AppStartTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.appstart; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | 10 | /** 11 | * 应用启动时间 数据表 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public class AppStartTable implements ITable { 16 | @Override 17 | public String createSql() { 18 | return TextUtils.concat( 19 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 20 | "(", AppStartInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 21 | AppStartInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 22 | AppStartInfo.KEY_START_TIME, DbHelper.DATA_TYPE_INTEGER, 23 | AppStartInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 24 | AppStartInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 25 | AppStartInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 26 | ).toString(); 27 | } 28 | 29 | @Override 30 | public String getTableName() { 31 | return ApmTask.TASK_APP_START; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/appstart/AppStartTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.appstart; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.storage.IStorage; 5 | import com.argusapm.android.core.tasks.BaseTask; 6 | 7 | /** 8 | * 应用启动Task 9 | * 10 | * @author ArgusAPM Team 11 | */ 12 | public class AppStartTask extends BaseTask { 13 | 14 | @Override 15 | protected IStorage getStorage() { 16 | return new AppStartStorage(); 17 | } 18 | 19 | @Override 20 | public String getTaskName() { 21 | return ApmTask.TASK_APP_START; 22 | } 23 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/block/BlockInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.block; 2 | 3 | import android.content.ContentValues; 4 | 5 | import com.argusapm.android.core.BaseInfo; 6 | import com.argusapm.android.core.job.processinfo.ProcessInfo; 7 | import com.argusapm.android.utils.LogX; 8 | import com.argusapm.android.utils.ProcessUtils; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import static com.argusapm.android.Env.DEBUG; 14 | import static com.argusapm.android.Env.TAG; 15 | 16 | /** 17 | * 卡顿信息 18 | * 19 | * @author ArgusAPM Team 20 | */ 21 | public class BlockInfo extends BaseInfo { 22 | private final String SUB_TAG = "BlockInfo"; 23 | 24 | 25 | public String processName;//进程名称 26 | public String blockStack; 27 | public int blockTime; 28 | 29 | public static class DBKey { 30 | public static final String PROCESS_NAME = "pn"; //进程名称 31 | public static final String BLOCK_STACK = "stack"; 32 | public static final String BLOCK_TIME = "bt"; 33 | } 34 | 35 | public BlockInfo() { 36 | processName = ProcessUtils.getCurrentProcessName(); 37 | } 38 | 39 | @Override 40 | public JSONObject toJson() throws JSONException { 41 | JSONObject ori = super.toJson() 42 | .put(BlockInfo.DBKey.PROCESS_NAME, processName) 43 | .put(BlockInfo.DBKey.BLOCK_STACK, blockStack) 44 | .put(BlockInfo.DBKey.BLOCK_TIME, blockTime); 45 | return ori; 46 | } 47 | 48 | @Override 49 | public void parserJsonStr(String json) throws JSONException { 50 | parserJson(new JSONObject(json)); 51 | } 52 | 53 | @Override 54 | public void parserJson(JSONObject json) throws JSONException { 55 | this.processName = json.getString(DBKey.PROCESS_NAME); 56 | this.blockStack = json.getString(DBKey.BLOCK_STACK); 57 | this.blockTime = json.getInt(DBKey.BLOCK_TIME); 58 | } 59 | 60 | @Override 61 | public ContentValues toContentValues() { 62 | ContentValues values = new ContentValues(); 63 | try { 64 | values.put(DBKey.PROCESS_NAME, processName); 65 | values.put(DBKey.BLOCK_STACK, blockStack); 66 | values.put(DBKey.BLOCK_TIME, blockTime); 67 | } catch (Exception e) { 68 | if (DEBUG) { 69 | LogX.e(TAG, SUB_TAG, e.toString()); 70 | } 71 | } 72 | return values; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/block/BlockStorage.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.block; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.IInfo; 7 | import com.argusapm.android.core.Manager; 8 | import com.argusapm.android.core.storage.TableStorage; 9 | import com.argusapm.android.utils.IOStreamUtils; 10 | import com.argusapm.android.utils.LogX; 11 | 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | import static com.argusapm.android.Env.DEBUG; 16 | import static com.argusapm.android.Env.TAG; 17 | 18 | /** 19 | * 卡顿信息存储 20 | * 21 | * @author ArgusAPM Team 22 | */ 23 | public class BlockStorage extends TableStorage { 24 | private final String SUB_TAG = "BlockStorage"; 25 | 26 | @Override 27 | public String getName() { 28 | return ApmTask.TASK_BLOCK; 29 | } 30 | 31 | @Override 32 | public List readDb(String selection) { 33 | List infos = new LinkedList(); 34 | Cursor cursor = null; 35 | try { 36 | cursor = Manager.getInstance().getConfig().appContext.getContentResolver() 37 | .query(getTableUri(), null, selection, null, null); 38 | if (null == cursor || !cursor.moveToFirst()) { 39 | IOStreamUtils.closeQuietly(cursor); 40 | return infos; 41 | } 42 | int indexTimeRecord = cursor.getColumnIndex(BlockInfo.KEY_TIME_RECORD); 43 | int indexProcessName = cursor.getColumnIndex(BlockInfo.DBKey.PROCESS_NAME); 44 | int indexBlockStack = cursor.getColumnIndex(BlockInfo.DBKey.BLOCK_STACK); 45 | int indexBlockTime = cursor.getColumnIndex(BlockInfo.DBKey.BLOCK_TIME); 46 | do { 47 | BlockInfo blockInfo = new BlockInfo(); 48 | blockInfo.processName = cursor.getString(indexProcessName); 49 | blockInfo.blockStack = cursor.getString(indexBlockStack); 50 | blockInfo.blockTime = cursor.getInt(indexBlockTime); 51 | blockInfo.setRecordTime(cursor.getLong(indexTimeRecord)); 52 | infos.add(blockInfo); 53 | } while (cursor.moveToNext()); 54 | } catch (Exception e) { 55 | if (DEBUG) { 56 | LogX.e(TAG, SUB_TAG, getName() + "; " + e.toString()); 57 | } 58 | } finally { 59 | IOStreamUtils.closeQuietly(cursor); 60 | } 61 | return infos; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/block/BlockTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.block; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.job.processinfo.ProcessInfo; 7 | import com.argusapm.android.core.storage.DbHelper; 8 | import com.argusapm.android.core.storage.ITable; 9 | 10 | /** 11 | * 卡顿模块表 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public class BlockTable implements ITable { 16 | @Override 17 | public String createSql() { 18 | return TextUtils.concat( 19 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 20 | "(", ProcessInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 21 | BlockInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 22 | BlockInfo.DBKey.PROCESS_NAME, DbHelper.DATA_TYPE_TEXT, 23 | BlockInfo.DBKey.BLOCK_STACK, DbHelper.DATA_TYPE_TEXT, 24 | BlockInfo.DBKey.BLOCK_TIME, DbHelper.DATA_TYPE_INTEGER, 25 | BlockInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 26 | BlockInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 27 | BlockInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 28 | ).toString(); 29 | } 30 | 31 | @Override 32 | public String getTableName() { 33 | return ApmTask.TASK_BLOCK; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/fileinfo/FileTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.fileinfo; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * 文件表 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class FileTable implements ITable { 15 | @Override 16 | public String createSql() { 17 | return TextUtils.concat(DbHelper.CREATE_TABLE_PREFIX + getTableName(), 18 | "(", FileInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 19 | FileInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 20 | FileInfo.DBKey.KEY_FILE_NAME, DbHelper.DATA_TYPE_TEXT, 21 | FileInfo.DBKey.KEY_FILE_PATH, DbHelper.DATA_TYPE_TEXT, 22 | FileInfo.DBKey.KEY_FILE_TYPE, DbHelper.DATA_TYPE_INTEGER, 23 | FileInfo.DBKey.KEY_LAST_MODIFIED, DbHelper.DATA_TYPE_INTEGER, 24 | FileInfo.DBKey.KEY_FILE_SIZE, DbHelper.DATA_TYPE_INTEGER, 25 | FileInfo.DBKey.KEY_READABLE, DbHelper.DATA_TYPE_INTEGER, 26 | FileInfo.DBKey.KEY_WRITABLE, DbHelper.DATA_TYPE_INTEGER, 27 | FileInfo.DBKey.KEY_EXECUTABLE, DbHelper.DATA_TYPE_INTEGER, 28 | FileInfo.DBKey.KEY_SUB_FILE_NUM, DbHelper.DATA_TYPE_INTEGER, 29 | FileInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 30 | FileInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 31 | FileInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF).toString(); 32 | } 33 | 34 | @Override 35 | public String getTableName() { 36 | return ApmTask.TASK_FILE_INFO; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/fps/FpsTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.fps; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.android.internal.http.multipart.FilePartSource; 6 | import com.argusapm.android.api.ApmTask; 7 | import com.argusapm.android.core.storage.DbHelper; 8 | import com.argusapm.android.core.storage.ITable; 9 | 10 | /** 11 | * @author ArgusAPM Team 12 | */ 13 | public class FpsTable implements ITable { 14 | @Override 15 | public String createSql() { 16 | return TextUtils.concat( 17 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 18 | "(", FpsInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 19 | FpsInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 20 | FpsInfo.KEY_TYPE, DbHelper.DATA_TYPE_INTEGER, 21 | FpsInfo.KEY_ACTIVITY, DbHelper.DATA_TYPE_TEXT, 22 | FpsInfo.KEY_FPS, DbHelper.DATA_TYPE_INTEGER, 23 | FpsInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 24 | FpsInfo.KEY_PROCESS_NAME, DbHelper.DATA_TYPE_TEXT, 25 | FpsInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 26 | FpsInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 27 | ).toString(); 28 | } 29 | 30 | @Override 31 | public String getTableName() { 32 | return ApmTask.TASK_FPS; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/func/AopFuncTrace.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.func; 2 | 3 | import com.argusapm.android.aop.IAopTraceHelper; 4 | 5 | /** 6 | * @author ArgusAPM Team 7 | */ 8 | public class AopFuncTrace implements IAopTraceHelper { 9 | @Override 10 | public void dispatch(long startTime, String kind, String sign, Object[] args, Object target, Object thiz, String location, String staticPartStr, String methodName, Object result) { 11 | FuncTrace.dispatch(startTime, kind, sign, args, target, thiz, location, staticPartStr, methodName, result); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/func/FuncInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.func; 2 | 3 | import android.content.ContentValues; 4 | import android.text.TextUtils; 5 | 6 | import com.argusapm.android.core.BaseInfo; 7 | 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | 11 | /** 12 | * @author ArgusAPM Team 13 | */ 14 | public class FuncInfo extends BaseInfo { 15 | public static final String SUB_TAG = "tracefunc"; 16 | 17 | public static final int FUNC_TYPE_UNKNOWN = 0; 18 | public static final int FUNC_TYPE_RUN = 1; 19 | public static final int FUNC_TYPE_ONRECEIVE = 2; 20 | 21 | public static final String KEY_TYPE = "ty"; 22 | 23 | public static final String KEY_COST = "cost"; 24 | public static final String KEY_LOCATION = "loc"; 25 | 26 | private int type = FUNC_TYPE_UNKNOWN; 27 | 28 | public int getType() { 29 | return type; 30 | } 31 | 32 | public void setType(int type) { 33 | this.type = type; 34 | } 35 | 36 | @Override 37 | public JSONObject toJson() throws JSONException { 38 | JSONObject ori = super.toJson() 39 | .put(KEY_TYPE, type); 40 | if (!TextUtils.isEmpty(params)) { 41 | ori.put(KEY_PARAM, params); 42 | } 43 | return ori; 44 | } 45 | 46 | @Override 47 | public void parserJsonStr(String json) throws JSONException { 48 | parserJson(new JSONObject(json)); 49 | } 50 | 51 | @Override 52 | public void parserJson(JSONObject json) throws JSONException { 53 | if (json.has(KEY_TYPE)) { 54 | type = json.getInt(KEY_TYPE); 55 | } 56 | if (json.has(KEY_PARAM)) { 57 | params = json.getString(KEY_PARAM); 58 | } 59 | } 60 | 61 | @Override 62 | public ContentValues toContentValues() { 63 | ContentValues values = new ContentValues(); 64 | values.put(KEY_TYPE, type); 65 | values.put(KEY_PARAM, params); 66 | return values; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/func/FuncStorage.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.func; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.IInfo; 7 | import com.argusapm.android.core.Manager; 8 | import com.argusapm.android.core.storage.TableStorage; 9 | import com.argusapm.android.utils.IOStreamUtils; 10 | import com.argusapm.android.utils.LogX; 11 | 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | import static com.argusapm.android.Env.TAG; 16 | 17 | /** 18 | * @author ArgusAPM Team 19 | */ 20 | public class FuncStorage extends TableStorage { 21 | @Override 22 | public List readDb(String selection) { 23 | List infoList = new LinkedList(); 24 | Cursor cursor = null; 25 | try { 26 | cursor = Manager.getInstance().getConfig().appContext.getContentResolver() 27 | .query(getTableUri(), null, selection, null, null); 28 | if (null == cursor || !cursor.moveToNext()) { 29 | IOStreamUtils.closeQuietly(cursor); 30 | return infoList; 31 | } 32 | 33 | int indexId = cursor.getColumnIndex(FuncInfo.KEY_ID_RECORD); 34 | int indexTimeRecord = cursor.getColumnIndex(FuncInfo.KEY_TIME_RECORD); 35 | int indexType = cursor.getColumnIndex(FuncInfo.KEY_TYPE); 36 | int indexParams = cursor.getColumnIndex(FuncInfo.KEY_PARAM); 37 | do { 38 | FuncInfo info = new FuncInfo(); 39 | info.setRecordTime(cursor.getLong(indexTimeRecord)); 40 | info.setType(cursor.getInt(indexType)); 41 | info.setParams(cursor.getString(indexParams)); 42 | infoList.add(info); 43 | } while (cursor.moveToNext()); 44 | 45 | } catch (Exception e) { 46 | LogX.e(TAG, SUB_TAG, getName() + "; " + e.toString()); 47 | } finally { 48 | IOStreamUtils.closeQuietly(cursor); 49 | } 50 | return infoList; 51 | } 52 | 53 | @Override 54 | public String getName() { 55 | return ApmTask.TASK_FUNC; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/func/FuncTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.func; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * @author ArgusAPM Team 11 | */ 12 | public class FuncTable implements ITable { 13 | @Override 14 | public String createSql() { 15 | return TextUtils.concat( 16 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 17 | "(", FuncInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 18 | FuncInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 19 | FuncInfo.KEY_TYPE, DbHelper.DATA_TYPE_TEXT, 20 | FuncInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 21 | FuncInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 22 | FuncInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 23 | ).toString(); 24 | } 25 | 26 | @Override 27 | public String getTableName() { 28 | return ApmTask.TASK_FUNC; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/func/FuncTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.func; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.storage.IStorage; 5 | import com.argusapm.android.core.tasks.BaseTask; 6 | 7 | /** 8 | * @author ArgusAPM Team 9 | */ 10 | public class FuncTask extends BaseTask { 11 | @Override 12 | protected IStorage getStorage() { 13 | return new FuncStorage(); 14 | } 15 | 16 | @Override 17 | public String getTaskName() { 18 | return ApmTask.TASK_FUNC; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/memory/MemoryTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.memory; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * @author ArgusAPM Team 11 | */ 12 | public class MemoryTable implements ITable { 13 | @Override 14 | public String createSql() { 15 | return TextUtils.concat( 16 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 17 | "(", MemoryInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 18 | MemoryInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 19 | MemoryInfo.KEY_PROCESS_NAME, DbHelper.DATA_TYPE_TEXT, 20 | MemoryInfo.KEY_TOTAL_PSS, DbHelper.DATA_TYPE_INTEGER, 21 | MemoryInfo.KEY_DALVIK_PSS, DbHelper.DATA_TYPE_INTEGER, 22 | MemoryInfo.KEY_NATIVE_PSS, DbHelper.DATA_TYPE_INTEGER, 23 | MemoryInfo.KEY_OTHER_PSS, DbHelper.DATA_TYPE_INTEGER, 24 | MemoryInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 25 | MemoryInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 26 | MemoryInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 27 | ).toString(); 28 | } 29 | 30 | @Override 31 | public String getTableName() { 32 | return ApmTask.TASK_MEM; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/NetTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * @author ArgusAPM Team 11 | */ 12 | public class NetTable implements ITable { 13 | 14 | @Override 15 | public String createSql() { 16 | return TextUtils.concat( 17 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 18 | "(", NetInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 19 | NetInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 20 | NetInfo.KEY_URL, DbHelper.DATA_TYPE_TEXT, 21 | NetInfo.KEY_STATUS_CODE, DbHelper.DATA_TYPE_INTEGER, 22 | NetInfo.KEY_ERROR_CODE, DbHelper.DATA_TYPE_INTEGER, 23 | NetInfo.KEY_RECEIVE_BYTES, DbHelper.DATA_TYPE_INTEGER, 24 | NetInfo.KEY_SEND_BYTES, DbHelper.DATA_TYPE_INTEGER, 25 | NetInfo.KEY_IS_WIFI, DbHelper.DATA_TYPE_INTEGER, 26 | NetInfo.KEY_TIME_START, DbHelper.DATA_TYPE_INTEGER, 27 | NetInfo.KEY_TIME_COST, DbHelper.DATA_TYPE_INTEGER, 28 | NetInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 29 | NetInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 30 | NetInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 31 | ).toString(); 32 | } 33 | 34 | @Override 35 | public String getTableName() { 36 | return ApmTask.TASK_NET; 37 | } 38 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/NetTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.storage.IStorage; 5 | import com.argusapm.android.core.tasks.BaseTask; 6 | 7 | /** 8 | * @author ArgusAPM Team 9 | */ 10 | public class NetTask extends BaseTask { 11 | 12 | @Override 13 | protected IStorage getStorage() { 14 | return new NetStorage(); 15 | } 16 | 17 | @Override 18 | public String getTaskName() { 19 | return ApmTask.TASK_NET; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/i/IStreamCompleteListener.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net.i; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public interface IStreamCompleteListener { 7 | 8 | void onInputstreamComplete(long size); 9 | 10 | void onOutputstreamComplete(long size); 11 | 12 | void onInputstreamError(long size); 13 | 14 | void onOutputstreamError(long size); 15 | } 16 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/i/QOKHttp.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net.i; 2 | 3 | import com.argusapm.android.core.job.net.NetInfo; 4 | 5 | /** 6 | * OkHttp相关,对外暴露的接口 7 | * 8 | * @author ArgusAPM Team 9 | */ 10 | public class QOKHttp { 11 | 12 | /** 13 | * 记录一次网络请求 14 | * 15 | * @param url 请求url 16 | * @param code 状态码 17 | * @param requestSize 发送的数据大小 18 | * @param responseSize 接收的数据大小 19 | * @param startTime 发起时间 20 | * @param costTime 耗时 21 | */ 22 | public static void recordUrlRequest(String url, int code, long requestSize, long responseSize, 23 | long startTime, long costTime) { 24 | NetInfo netInfo = new NetInfo(); 25 | netInfo.setStartTime(startTime); 26 | netInfo.setURL(url); 27 | netInfo.setStatusCode(code); 28 | netInfo.setSendBytes(requestSize); 29 | netInfo.setRecordTime(System.currentTimeMillis()); 30 | netInfo.setReceivedBytes(responseSize); 31 | netInfo.setCostTime(costTime); 32 | netInfo.end(); 33 | } 34 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/i/QURL.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net.i; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.Manager; 5 | import com.argusapm.android.core.job.net.impl.AopURL; 6 | 7 | import java.io.IOException; 8 | import java.net.Proxy; 9 | import java.net.URL; 10 | import java.net.URLConnection; 11 | 12 | /** 13 | * aop 代码织入时会调用 14 | * 15 | * @author ArgusAPM Team 16 | */ 17 | public class QURL { 18 | 19 | public static URLConnection openConnection(URL url) throws IOException { 20 | return isNetTaskRunning() ? AopURL.openConnection(url) : url.openConnection(); 21 | } 22 | 23 | public static URLConnection openConnection(URL url, Proxy proxy) throws IOException { 24 | return isNetTaskRunning() ? AopURL.openConnection(url, proxy) : url.openConnection(proxy); 25 | } 26 | 27 | private static boolean isNetTaskRunning() { 28 | return Manager.getInstance().getTaskManager().taskIsCanWork(ApmTask.TASK_NET); 29 | } 30 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/impl/AopResponseHandler.java: -------------------------------------------------------------------------------- 1 | 2 | package com.argusapm.android.core.job.net.impl; 3 | 4 | import com.argusapm.android.core.job.net.NetInfo; 5 | import com.argusapm.android.utils.LogX; 6 | 7 | import org.apache.http.Header; 8 | import org.apache.http.HttpResponse; 9 | import org.apache.http.client.ResponseHandler; 10 | 11 | import java.io.IOException; 12 | 13 | import static com.argusapm.android.Env.DEBUG; 14 | import static com.argusapm.android.Env.TAG; 15 | 16 | /** 17 | * @author ArgusAPM Team 18 | */ 19 | public class AopResponseHandler implements ResponseHandler { 20 | 21 | private final String SUB_TAG = "AopResponseHandler"; 22 | private final ResponseHandler myHandler; 23 | 24 | private final NetInfo myData; 25 | 26 | private AopResponseHandler(ResponseHandler responseHandler, NetInfo data) { 27 | this.myHandler = responseHandler; 28 | this.myData = data; 29 | } 30 | 31 | @Override 32 | public T handleResponse(HttpResponse response) throws IOException { 33 | myData.setStatusCode(response.getStatusLine().getStatusCode()); 34 | Header[] headers = response.getHeaders("Content-Length"); 35 | if ((headers != null) && (headers.length > 0)) { 36 | try { 37 | long l = Long.parseLong(headers[0].getValue()); 38 | myData.setReceivedBytes(l); 39 | if (DEBUG) { 40 | LogX.d(TAG, SUB_TAG, "-AopResponseHandler-------Response handler--end--1"); 41 | } 42 | myData.end(); 43 | } catch (NumberFormatException e) { 44 | 45 | } 46 | } else if (response.getEntity() != null) { 47 | response.setEntity(new AopHttpResponseEntity(response.getEntity(), myData)); 48 | } else { 49 | myData.setReceivedBytes(0); 50 | if (DEBUG) { 51 | LogX.d(TAG, SUB_TAG, "--AopResponseHandler------Response handler--end--2"); 52 | } 53 | myData.end(); 54 | } 55 | return myHandler.handleResponse(response); 56 | } 57 | 58 | @SuppressWarnings({ 59 | "rawtypes", "unchecked" 60 | }) 61 | public static ResponseHandler wrap(ResponseHandler responseHandler, NetInfo data) { 62 | return new AopResponseHandler(responseHandler, data); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/net/impl/AopURL.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.net.impl; 2 | 3 | import com.argusapm.android.Env; 4 | import com.argusapm.android.utils.LogX; 5 | 6 | import java.io.IOException; 7 | import java.net.HttpURLConnection; 8 | import java.net.Proxy; 9 | import java.net.URL; 10 | import java.net.URLConnection; 11 | 12 | import javax.net.ssl.HttpsURLConnection; 13 | 14 | import static com.argusapm.android.Env.TAG; 15 | 16 | /** 17 | * @author ArgusAPM Team 18 | */ 19 | public class AopURL { 20 | public static URLConnection openConnection(URL url) throws IOException { 21 | if (url == null) { 22 | return null; 23 | } 24 | return getAopConnection(url.openConnection()); 25 | } 26 | 27 | public static URLConnection openConnection(URL url, Proxy proxy) throws IOException { 28 | if (url == null) { 29 | return null; 30 | } 31 | return getAopConnection(url.openConnection(proxy)); 32 | } 33 | 34 | private static URLConnection getAopConnection(URLConnection con) { 35 | if (con == null) { 36 | return null; 37 | } 38 | if (Env.DEBUG) { 39 | LogX.d(TAG, "AopURL", "getAopConnection in AopURL"); 40 | } 41 | if ((con instanceof HttpsURLConnection)) { 42 | return new AopHttpsURLConnection((HttpsURLConnection) con); 43 | } 44 | if ((con instanceof HttpURLConnection)) { 45 | return new AopHttpURLConnection((HttpURLConnection) con); 46 | } 47 | return con; 48 | } 49 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/processinfo/ProcessInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.processinfo; 2 | 3 | import android.content.ContentValues; 4 | 5 | import com.argusapm.android.core.BaseInfo; 6 | import com.argusapm.android.utils.LogX; 7 | import com.argusapm.android.utils.ProcessUtils; 8 | 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | import static com.argusapm.android.Env.DEBUG; 13 | import static com.argusapm.android.Env.TAG; 14 | 15 | /** 16 | * 进程信息 17 | * 18 | * @author ArgusAPM Team 19 | */ 20 | public class ProcessInfo extends BaseInfo { 21 | private final String SUB_TAG = "ProcessInfo"; 22 | 23 | 24 | public String processName;//进程名称 25 | public int startCount = 1;//启动次数 26 | 27 | public static class DBKey { 28 | public static final String PROCESS_NAME = "pn"; //进程名称 29 | public static final String START_COUNT = "sc"; //进程启动次数 30 | } 31 | 32 | public ProcessInfo() { 33 | processName = ProcessUtils.getCurrentProcessName(); 34 | } 35 | 36 | @Override 37 | public JSONObject toJson() throws JSONException { 38 | JSONObject ori = super.toJson() 39 | .put(DBKey.PROCESS_NAME, processName) 40 | .put(DBKey.START_COUNT, startCount); 41 | return ori; 42 | } 43 | 44 | @Override 45 | public void parserJsonStr(String json) throws JSONException { 46 | parserJson(new JSONObject(json)); 47 | } 48 | 49 | @Override 50 | public void parserJson(JSONObject json) throws JSONException { 51 | this.processName = json.getString(DBKey.PROCESS_NAME); 52 | this.startCount = json.getInt(DBKey.START_COUNT); 53 | } 54 | 55 | @Override 56 | public ContentValues toContentValues() { 57 | ContentValues values = new ContentValues(); 58 | try { 59 | values.put(DBKey.PROCESS_NAME, processName); 60 | values.put(DBKey.START_COUNT, startCount); 61 | } catch (Exception e) { 62 | if (DEBUG) { 63 | LogX.e(TAG, SUB_TAG, e.toString()); 64 | } 65 | } 66 | return values; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/processinfo/ProcessInfoStorage.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.processinfo; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.IInfo; 7 | import com.argusapm.android.core.Manager; 8 | import com.argusapm.android.core.storage.TableStorage; 9 | import com.argusapm.android.utils.IOStreamUtils; 10 | import com.argusapm.android.utils.LogX; 11 | 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | import static com.argusapm.android.Env.DEBUG; 16 | import static com.argusapm.android.Env.TAG; 17 | 18 | /** 19 | * 进程信息存储类 20 | * 21 | * @author ArgusAPM Team 22 | */ 23 | public class ProcessInfoStorage extends TableStorage { 24 | private final String SUB_TAG = "ProcessInfoStorage"; 25 | 26 | @Override 27 | public String getName() { 28 | return ApmTask.TASK_PROCESS_INFO; 29 | } 30 | 31 | @Override 32 | public List readDb(String selection) { 33 | List infos = new LinkedList(); 34 | Cursor cursor = null; 35 | try { 36 | cursor = Manager.getInstance().getConfig().appContext.getContentResolver() 37 | .query(getTableUri(), null, selection, null, null); 38 | if (null == cursor || !cursor.moveToFirst()) { 39 | IOStreamUtils.closeQuietly(cursor); 40 | return infos; 41 | } 42 | int indexTimeRecord = cursor.getColumnIndex(ProcessInfo.KEY_TIME_RECORD); 43 | int indexProcessName = cursor.getColumnIndex(ProcessInfo.DBKey.PROCESS_NAME); 44 | int indexStartCount = cursor.getColumnIndex(ProcessInfo.DBKey.START_COUNT); 45 | do { 46 | ProcessInfo processInfo = new ProcessInfo(); 47 | processInfo.processName = cursor.getString(indexProcessName); 48 | processInfo.startCount = cursor.getInt(indexStartCount); 49 | processInfo.setRecordTime(cursor.getLong(indexTimeRecord)); 50 | infos.add(processInfo); 51 | } while (cursor.moveToNext()); 52 | } catch (Exception e) { 53 | if (DEBUG) { 54 | LogX.e(TAG, SUB_TAG, getName() + "; " + e.toString()); 55 | } 56 | } finally { 57 | IOStreamUtils.closeQuietly(cursor); 58 | } 59 | return infos; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/processinfo/ProcessInfoTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.processinfo; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.Manager; 5 | import com.argusapm.android.core.storage.IStorage; 6 | import com.argusapm.android.core.tasks.BaseTask; 7 | import com.argusapm.android.core.tasks.ITask; 8 | import com.argusapm.android.utils.AsyncThreadTask; 9 | import com.argusapm.android.utils.LogX; 10 | 11 | import static com.argusapm.android.Env.DEBUG; 12 | import static com.argusapm.android.Env.TAG; 13 | 14 | /** 15 | * 进程信息任务类 16 | * 17 | * @author ArgusAPM Team 18 | */ 19 | public class ProcessInfoTask extends BaseTask { 20 | 21 | @Override 22 | public void start() { 23 | super.start(); 24 | saveProcessInfo(); 25 | } 26 | 27 | /** 28 | * 保存进程相关信息 29 | */ 30 | private void saveProcessInfo() { 31 | AsyncThreadTask.executeDelayed(new Runnable() { 32 | @Override 33 | public void run() { 34 | if (!isCanWork()) { 35 | return; 36 | } 37 | ProcessInfo info = new ProcessInfo(); 38 | ITask task = Manager.getInstance().getTaskManager().getTask(ApmTask.TASK_PROCESS_INFO); 39 | if (task != null) { 40 | task.save(info); 41 | } else { 42 | if (DEBUG) { 43 | LogX.d(TAG, "Client", "ProcessInfo task == null"); 44 | } 45 | } 46 | } 47 | }, 2000 + (int) (Math.round(Math.random() * 1000))); 48 | } 49 | 50 | @Override 51 | protected IStorage getStorage() { 52 | return new ProcessInfoStorage(); 53 | } 54 | 55 | @Override 56 | public String getTaskName() { 57 | return ApmTask.TASK_PROCESS_INFO; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/processinfo/ProgessInfoTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.processinfo; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * 进程信息数据表 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class ProgessInfoTable implements ITable { 15 | @Override 16 | public String createSql() { 17 | return TextUtils.concat( 18 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 19 | "(", ProcessInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 20 | ProcessInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 21 | ProcessInfo.DBKey.PROCESS_NAME, DbHelper.DATA_TYPE_TEXT, 22 | ProcessInfo.DBKey.START_COUNT, DbHelper.DATA_TYPE_INTEGER, 23 | ProcessInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 24 | ProcessInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 25 | ProcessInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 26 | ).toString(); 27 | } 28 | 29 | @Override 30 | public String getTableName() { 31 | return ApmTask.TASK_PROCESS_INFO; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/watchDog/WatchDogInfo.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.watchDog; 2 | 3 | import com.argusapm.android.core.job.block.BlockInfo; 4 | 5 | /** 6 | * @author ArgusAPM Team 7 | */ 8 | public class WatchDogInfo extends BlockInfo { 9 | private final String SUB_TAG = "WachDogInfo"; 10 | } 11 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/watchDog/WatchDogInfoTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.watchDog; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.job.block.BlockInfo; 7 | import com.argusapm.android.core.job.processinfo.ProcessInfo; 8 | import com.argusapm.android.core.storage.DbHelper; 9 | import com.argusapm.android.core.storage.ITable; 10 | 11 | /** 12 | * @author ArgusAPM Team 13 | */ 14 | public class WatchDogInfoTable implements ITable { 15 | @Override 16 | public String createSql() { 17 | return TextUtils.concat( 18 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 19 | "(", ProcessInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 20 | BlockInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 21 | BlockInfo.DBKey.PROCESS_NAME, DbHelper.DATA_TYPE_TEXT, 22 | BlockInfo.DBKey.BLOCK_STACK, DbHelper.DATA_TYPE_TEXT, 23 | BlockInfo.DBKey.BLOCK_TIME, DbHelper.DATA_TYPE_INTEGER, 24 | BlockInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 25 | BlockInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 26 | BlockInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 27 | ).toString(); 28 | } 29 | 30 | @Override 31 | public String getTableName() { 32 | return ApmTask.TASK_WATCHDOG; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/webview/AopWebTrace.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.webview; 2 | 3 | import org.json.JSONObject; 4 | 5 | /** 6 | * 通过AOP切面调用,不要轻易更改文件所有的包路径和类名 7 | * 8 | * @author ArgusAPM Team 9 | */ 10 | public class AopWebTrace { 11 | public static void dispatch(JSONObject jsonObject) { 12 | WebTrace.dispatch(jsonObject); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/webview/JSBridge.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.webview; 2 | 3 | import android.util.Log; 4 | import android.webkit.JavascriptInterface; 5 | 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | public class JSBridge { 10 | private static final String TAG = "JSBridge"; 11 | public static final String JS_INTERFACE_NAME = "android_apm"; 12 | public static final String JS_MONITOR = "javascript:%s.sendResource(JSON.stringify(window.performance.timing));"; 13 | private String mThisUrl; 14 | 15 | public JSBridge(String url) { 16 | mThisUrl = url; 17 | } 18 | 19 | 20 | /** 21 | * 用于收集Timing信息 22 | * 23 | * @param jsonStr 24 | */ 25 | @JavascriptInterface 26 | public void sendResource(String jsonStr) { 27 | dispatchToAopWebTrace(jsonStr, mThisUrl); 28 | } 29 | 30 | /** 31 | * 用于收集js的执行错误 32 | * 33 | * @param msg 34 | */ 35 | @JavascriptInterface 36 | public void sendError(String msg) { 37 | 38 | } 39 | 40 | 41 | private void dispatchToAopWebTrace(String jsonStr, String url) { 42 | try { 43 | JSONObject source = new JSONObject(jsonStr); 44 | final JSONObject destObject = new JSONObject(); 45 | destObject.put("ns", source.getLong("navigationStart")); 46 | destObject.put("pt", System.currentTimeMillis()); 47 | destObject.put("rs", source.getLong("responseStart")); 48 | destObject.put("u", url); 49 | AopWebTrace.dispatch(destObject); 50 | } catch (JSONException e) { 51 | e.printStackTrace(); 52 | Log.e(TAG, "Method: addJavascriptInterface()" + e.getMessage()); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/webview/WebTable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.webview; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.storage.DbHelper; 7 | import com.argusapm.android.core.storage.ITable; 8 | 9 | /** 10 | * @author ArgusAPM Team 11 | */ 12 | public class WebTable implements ITable { 13 | @Override 14 | public String createSql() { 15 | return TextUtils.concat( 16 | DbHelper.CREATE_TABLE_PREFIX + getTableName(), 17 | "(", WebInfo.KEY_ID_RECORD, " INTEGER PRIMARY KEY AUTOINCREMENT,", 18 | WebInfo.KEY_TIME_RECORD, DbHelper.DATA_TYPE_INTEGER, 19 | WebInfo.DBKey.KEY_URL, DbHelper.DATA_TYPE_TEXT, 20 | WebInfo.DBKey.KEY_IS_WIFI, DbHelper.DATA_TYPE_INTEGER, 21 | WebInfo.DBKey.KEY_NAVIGATION_START, DbHelper.DATA_TYPE_INTEGER, 22 | WebInfo.DBKey.KEY_RESPONSE_START, DbHelper.DATA_TYPE_INTEGER, 23 | WebInfo.DBKey.KEY_PAGE_TIME, DbHelper.DATA_TYPE_INTEGER, 24 | WebInfo.KEY_PARAM, DbHelper.DATA_TYPE_TEXT, 25 | WebInfo.KEY_RESERVE_1, DbHelper.DATA_TYPE_TEXT, 26 | WebInfo.KEY_RESERVE_2, DbHelper.DATA_TYPE_TEXT_SUF 27 | ).toString(); 28 | } 29 | 30 | @Override 31 | public String getTableName() { 32 | return ApmTask.TASK_WEBVIEW; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/webview/WebTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.webview; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.storage.IStorage; 5 | import com.argusapm.android.core.tasks.BaseTask; 6 | 7 | /** 8 | * @author ArgusAPM Team 9 | */ 10 | public class WebTask extends BaseTask { 11 | @Override 12 | protected IStorage getStorage() { 13 | return new WebStorage(); 14 | } 15 | 16 | @Override 17 | public String getTaskName() { 18 | return ApmTask.TASK_WEBVIEW; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/job/webview/WebTrace.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.job.webview; 2 | 3 | import com.argusapm.android.Env; 4 | import com.argusapm.android.api.ApmTask; 5 | import com.argusapm.android.core.Manager; 6 | import com.argusapm.android.core.tasks.ITask; 7 | import com.argusapm.android.utils.LogX; 8 | import com.argusapm.android.utils.SystemUtils; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | /** 14 | * @author ArgusAPM Team 15 | */ 16 | public class WebTrace { 17 | public static final String SUB_TAG = "traceweb"; 18 | 19 | public static void dispatch(JSONObject jsonObject) { 20 | if (!Manager.getInstance().getTaskManager().taskIsCanWork(ApmTask.TASK_WEBVIEW)) { 21 | if (Env.DEBUG) { 22 | LogX.d(Env.TAG, SUB_TAG, "webview task is not work"); 23 | } 24 | return; 25 | } 26 | ITask task = Manager.getInstance().getTaskManager().getTask(ApmTask.TASK_WEBVIEW); 27 | if (task != null && jsonObject != null) { 28 | try { 29 | WebInfo webInfo = new WebInfo(); 30 | webInfo.url = jsonObject.getString(WebInfo.DBKey.KEY_URL); 31 | webInfo.isWifi = SystemUtils.isWifiConnected(); 32 | webInfo.navigationStart = jsonObject.getLong(WebInfo.DBKey.KEY_NAVIGATION_START); 33 | webInfo.responseStart = jsonObject.getLong(WebInfo.DBKey.KEY_RESPONSE_START); 34 | webInfo.pageTime = jsonObject.getLong(WebInfo.DBKey.KEY_PAGE_TIME); 35 | task.save(webInfo); 36 | } catch (JSONException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/storage/DbSwitch.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.storage; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.helper.ApmDebugEnable; 6 | import com.argusapm.android.utils.LogX; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | import static com.argusapm.android.Env.DEBUG; 12 | import static com.argusapm.android.Env.TAG; 13 | 14 | /** 15 | * @author ArgusAPM Team 16 | */ 17 | public class DbSwitch { 18 | static Map dbSwitchList; 19 | private static final String SUB_TAG = "DbSwitch"; 20 | 21 | public static void updateSwitch(String taskName, boolean state) { 22 | synchronized (DbSwitch.class) { 23 | if (dbSwitchList == null) { 24 | dbSwitchList = new HashMap(); 25 | } 26 | if (TextUtils.isEmpty(taskName)) { 27 | return; 28 | } 29 | if (DEBUG) { 30 | LogX.d(TAG, SUB_TAG, "taskName :" + taskName + " state = " + state); 31 | } 32 | dbSwitchList.put(taskName, state); 33 | } 34 | } 35 | 36 | public static boolean getSwitchState(String taskName) { 37 | // 默认都为开 38 | Boolean state = true; 39 | synchronized (DbSwitch.class) { 40 | if (TextUtils.isEmpty(taskName)) { 41 | return state; 42 | } 43 | 44 | if (dbSwitchList == null) { 45 | dbSwitchList = new HashMap(); 46 | return state; 47 | } 48 | 49 | state = dbSwitchList.get(taskName); 50 | } 51 | if (state == null) { 52 | return true; 53 | } 54 | return state; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/storage/IStorage.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.storage; 2 | 3 | import android.content.ContentValues; 4 | 5 | import com.argusapm.android.core.IInfo; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 数据增删改查中间操作 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public interface IStorage { 15 | String getName(); 16 | 17 | IInfo get(Integer id); 18 | 19 | boolean save(IInfo data); 20 | 21 | int deleteByTime(long time); 22 | 23 | boolean delete(Integer id); 24 | 25 | // 按照一条id更新数据 26 | boolean update(Integer id, ContentValues cv); 27 | 28 | List getAll(); 29 | 30 | List getData(int index, int count); 31 | 32 | boolean clean(); 33 | 34 | boolean cleanByCount(int count); 35 | 36 | Object[] invoke(Object... args); 37 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/storage/ITable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.storage; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public interface ITable { 7 | 8 | String createSql(); 9 | 10 | String getTableName(); 11 | 12 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/storage/StorageUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.storage; 2 | 3 | import android.net.Uri; 4 | import android.text.TextUtils; 5 | 6 | import com.argusapm.android.core.StorageConfig; 7 | 8 | /** 9 | * 数据存储相关-工具类 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class StorageUtils { 14 | /** 15 | * 获取各任务table的uri 16 | * 17 | * @param pkgName 包名 18 | * @param tableName table名称 19 | * @return uri 20 | */ 21 | public static Uri getTableUri(String pkgName, String tableName) { 22 | if (TextUtils.isEmpty(pkgName) || TextUtils.isEmpty(tableName)) { 23 | return null; 24 | } 25 | String uriStr = TextUtils.concat( 26 | StorageConfig.CONTENT_PATH_PREFIX, 27 | getAuthority(pkgName), 28 | "/", 29 | tableName).toString(); 30 | return Uri.parse(uriStr); 31 | } 32 | 33 | /** 34 | * 获取AUTHORITY 35 | * 36 | * @param pkgName 包名 37 | * @return 38 | */ 39 | public static String getAuthority(String pkgName) { 40 | if (TextUtils.isEmpty(pkgName)) { 41 | return ""; 42 | } 43 | return TextUtils.concat(pkgName, ".", StorageConfig.AUTHORITY_SUFFIX).toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/tasks/BaseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.tasks; 2 | 3 | import com.argusapm.android.core.IInfo; 4 | import com.argusapm.android.core.storage.IStorage; 5 | import com.argusapm.android.utils.LogX; 6 | 7 | import static com.argusapm.android.Env.DEBUG; 8 | import static com.argusapm.android.Env.TAG; 9 | 10 | /** 11 | * ArgusAPM任务基类 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public abstract class BaseTask implements ITask { 16 | 17 | public static final String SUB_TAG = "BaseTask"; 18 | 19 | protected IStorage mStorage; 20 | 21 | protected boolean mIsCanWork = false; 22 | 23 | public BaseTask() { 24 | mStorage = getStorage(); 25 | } 26 | 27 | protected abstract IStorage getStorage(); 28 | 29 | @Override 30 | public void start() { 31 | if (DEBUG) { 32 | LogX.d(TAG, SUB_TAG, "start task :" + getTaskName()); 33 | } 34 | } 35 | 36 | @Override 37 | public boolean save(IInfo info) { 38 | if (DEBUG) { 39 | LogX.d(TAG, SUB_TAG, "save task :" + getTaskName()); 40 | } 41 | return info != null && mStorage != null && mStorage.save(info); 42 | } 43 | 44 | @Override 45 | public boolean isCanWork() { 46 | return mIsCanWork; 47 | } 48 | 49 | public void setCanWork(boolean canWork) { 50 | if (DEBUG) { 51 | LogX.d(TAG, SUB_TAG, "setCanWork task :" + getTaskName() + " :" + canWork); 52 | } 53 | mIsCanWork = canWork; 54 | } 55 | 56 | @Override 57 | public void stop() { 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/core/tasks/ITask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.core.tasks; 2 | 3 | import com.argusapm.android.core.IInfo; 4 | 5 | /** 6 | * ArgusAPM任务接口 7 | * 8 | * @author ArgusAPM Team 9 | */ 10 | public interface ITask { 11 | String getTaskName(); 12 | 13 | void start(); 14 | 15 | boolean isCanWork(); 16 | 17 | void setCanWork(boolean value); 18 | 19 | boolean save(IInfo info); 20 | 21 | void stop(); 22 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/callback/IDebugCallback.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.callback; 2 | 3 | /** 4 | * Debug模块回调接口 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public interface IDebugCallback { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/config/DebugConfig.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.config; 2 | 3 | /** 4 | * APM Debug模块配置信息 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class DebugConfig { 9 | 10 | public static int NET_REQUEST_SUCCESS = 200; 11 | public static String OUTPUT_FILE = "apm_debug_warning.txt";//存储文件名称 12 | public static int TEXT_COLOR_DEFAULT = 0xFFffffff;//白色文本 13 | public static int BIG_WINDOW_BG_COLOR = 0x99000000; //大悬浮窗背景颜色 14 | public static int TEXT_COLOR_GREEN = 0xff29a600; //绿色文本 15 | public static int TEXT_COLOR_WARN = 0xffff0000; //警告文本颜色 16 | public static int DEFAULT_PADDING = 10; 17 | public static int DEFAULT_TEXT_SIZE = 10; 18 | 19 | //警报阈值 20 | public static int WARN_ACTIVITY_CREATE_VALUE = 300; //Activity生命周期oncreate警报时间间隔 单位:ms 21 | public static int WARN_ACTIVITY_FRAME_VALUE = 500; //Activity生命周期第一帧警报时间间隔 单位:ms 22 | public static int WARN_FPS_VALUE = 40; 23 | public static int WARN_CPU_VALUE = 10; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/output/OutputProxy.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.output; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.debug.AnalyzeManager; 6 | import com.argusapm.android.debug.storage.StorageManager; 7 | 8 | /** 9 | * Debug模块输出代理类 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class OutputProxy { 14 | /** 15 | * 警报信息输出 16 | * 17 | * @param showMsg 18 | */ 19 | public static void output(String showMsg) { 20 | if (!AnalyzeManager.getInstance().isDebugMode()) { 21 | return; 22 | } 23 | if (TextUtils.isEmpty(showMsg)) { 24 | return; 25 | } 26 | //存储在本地 27 | StorageManager.saveToFile(showMsg); 28 | } 29 | 30 | /** 31 | * 警报信息输出 32 | * 33 | * @param showMsg toast展示输出 34 | * @param allMsg 所有信息 35 | */ 36 | public static void output(String showMsg, String allMsg) { 37 | if (!AnalyzeManager.getInstance().isDebugMode()) { 38 | return; 39 | } 40 | if (!TextUtils.isEmpty(allMsg)) { 41 | //存储在本地 42 | StorageManager.saveToFile(allMsg); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/storage/StorageManager.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.storage; 2 | 3 | import com.argusapm.android.Env; 4 | import com.argusapm.android.utils.LogX; 5 | 6 | /** 7 | * 日志数据存储管理类 8 | * 9 | * @author ArgusAPM Team 10 | */ 11 | public class StorageManager { 12 | /** 13 | * 按行保存到文本文件 14 | * 15 | * @param line 16 | */ 17 | public static void saveToFile(String line) { 18 | TraceWriter.log(Env.TAG, line); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/ActivityParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.IInfo; 5 | import com.argusapm.android.core.job.activity.ActivityInfo; 6 | import com.argusapm.android.debug.config.DebugConfig; 7 | import com.argusapm.android.debug.output.OutputProxy; 8 | import com.argusapm.android.debug.utils.DebugFloatWindowUtls; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | /** 14 | * Debug模块 Activity分析类 15 | * 16 | * @author ArgusAPM Team 17 | */ 18 | public class ActivityParseTask implements IParser { 19 | /** 20 | * 生命周期所用时间 21 | * 22 | * @param info 23 | */ 24 | @Override 25 | public boolean parse(IInfo info) { 26 | if (info instanceof ActivityInfo) { 27 | ActivityInfo aInfo = (ActivityInfo) info; 28 | if (aInfo == null) { 29 | return false; 30 | } 31 | if (aInfo.lifeCycle == ActivityInfo.TYPE_FIRST_FRAME) { 32 | saveWarningInfo(aInfo, DebugConfig.WARN_ACTIVITY_FRAME_VALUE); 33 | DebugFloatWindowUtls.sendBroadcast(aInfo); 34 | } else if (aInfo.lifeCycle == ActivityInfo.TYPE_CREATE) { 35 | saveWarningInfo(aInfo, DebugConfig.WARN_ACTIVITY_CREATE_VALUE); 36 | DebugFloatWindowUtls.sendBroadcast(aInfo); 37 | } else if (aInfo.lifeCycle == ActivityInfo.TYPE_RESUME) { 38 | saveWarningInfo(aInfo, DebugConfig.WARN_ACTIVITY_CREATE_VALUE); 39 | DebugFloatWindowUtls.sendBroadcast(aInfo); 40 | } else { 41 | saveWarningInfo(aInfo, DebugConfig.WARN_ACTIVITY_CREATE_VALUE); 42 | } 43 | } 44 | return true; 45 | } 46 | 47 | private void saveWarningInfo(ActivityInfo aInfo, int warningTime) { 48 | if (aInfo.time < warningTime) { 49 | return; 50 | } 51 | try { 52 | JSONObject obj = aInfo.toJson(); 53 | obj.put("taskName", ApmTask.TASK_ACTIVITY); 54 | OutputProxy.output("LifeCycle:" + aInfo.getLifeCycleString() + ",cost time:" + aInfo.time, obj.toString()); 55 | } catch (JSONException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/AppStartParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.IInfo; 5 | import com.argusapm.android.core.job.appstart.AppStartInfo; 6 | import com.argusapm.android.debug.output.OutputProxy; 7 | import com.argusapm.android.debug.utils.DebugFloatWindowUtls; 8 | 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | /** 13 | * Debug模块 应用启动时间分析类 14 | * 15 | * @author ArgusAPM Team 16 | */ 17 | public class AppStartParseTask implements IParser { 18 | /** 19 | * app启动 20 | * 21 | * @param info 22 | */ 23 | @Override 24 | public boolean parse(IInfo info) { 25 | if (info instanceof AppStartInfo) { 26 | AppStartInfo aInfo = (AppStartInfo) info; 27 | if (aInfo == null) { 28 | return false; 29 | } 30 | try { 31 | JSONObject obj = aInfo.toJson(); 32 | obj.put("taskName", ApmTask.TASK_APP_START); 33 | OutputProxy.output("启动时间:" + aInfo.getStartTime(), obj.toString()); 34 | } catch (JSONException e) { 35 | e.printStackTrace(); 36 | } 37 | DebugFloatWindowUtls.sendBroadcast(aInfo); 38 | } 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/FpsParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.argusapm.android.api.ApmTask; 6 | import com.argusapm.android.core.IInfo; 7 | import com.argusapm.android.core.job.fps.FpsInfo; 8 | import com.argusapm.android.debug.config.DebugConfig; 9 | import com.argusapm.android.debug.output.OutputProxy; 10 | import com.argusapm.android.debug.utils.DebugFloatWindowUtls; 11 | 12 | import org.json.JSONException; 13 | import org.json.JSONObject; 14 | 15 | /** 16 | * 分析帧率数据 17 | * 18 | * @author ArgusAPM Team 19 | */ 20 | public class FpsParseTask implements IParser { 21 | private JSONObject updateInfo(IInfo info, String taskName) { 22 | if (info == null || TextUtils.isEmpty(taskName)) { 23 | return null; 24 | } 25 | 26 | JSONObject json = null; 27 | try { 28 | json = info.toJson(); 29 | if (json != null) { 30 | json.put("taskName", taskName); 31 | } 32 | } catch (JSONException e) { 33 | e.printStackTrace(); 34 | } 35 | 36 | return json; 37 | } 38 | 39 | @Override 40 | public boolean parse(IInfo info) { 41 | if (info != null) { 42 | if (info instanceof FpsInfo) { 43 | FpsInfo fInfo = (FpsInfo) info; 44 | int fps = fInfo.getFps(); 45 | // fps次数越接近40,用户能感知到卡顿 46 | // 20以下卡顿更明显 47 | // 收集40以下的分析 48 | if (fps < DebugConfig.WARN_FPS_VALUE) { 49 | JSONObject obj = updateInfo(fInfo, ApmTask.TASK_FPS); 50 | OutputProxy.output(fInfo.toString(), obj.toString()); 51 | } 52 | DebugFloatWindowUtls.sendBroadcast(fInfo); 53 | } else { 54 | OutputProxy.output("what"); 55 | } 56 | } else { 57 | OutputProxy.output("info == null"); 58 | } 59 | return false; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/IParser.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.core.IInfo; 4 | 5 | /** 6 | * @author ArgusAPM Team 7 | */ 8 | public interface IParser { 9 | boolean parse(IInfo info); 10 | } 11 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/MemoryParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.IInfo; 5 | import com.argusapm.android.core.job.memory.MemoryInfo; 6 | import com.argusapm.android.debug.output.OutputProxy; 7 | import com.argusapm.android.debug.utils.DebugFloatWindowUtls; 8 | 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | /** 13 | * debug模式内存task 14 | * 15 | * @author ArgusAPM Team 16 | */ 17 | public class MemoryParseTask implements IParser { 18 | @Override 19 | public boolean parse(IInfo info) { 20 | if (info instanceof MemoryInfo) { 21 | MemoryInfo aInfo = (MemoryInfo) info; 22 | if (aInfo == null) { 23 | return false; 24 | } 25 | try { 26 | JSONObject obj = aInfo.toJson(); 27 | obj.put("taskName", ApmTask.TASK_MEM); 28 | OutputProxy.output("", obj.toString()); 29 | } catch (JSONException e) { 30 | e.printStackTrace(); 31 | } 32 | DebugFloatWindowUtls.sendBroadcast(aInfo); 33 | } 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/MonitorParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.core.IInfo; 4 | 5 | /** 6 | * @author ArgusAPM Team 7 | */ 8 | public class MonitorParseTask implements IParser { 9 | @Override 10 | public boolean parse(IInfo info) { 11 | // if (info != null && info instanceof MonitorInfo) { 12 | // MonitorInfo mInfo = (MonitorInfo) info; 13 | // try { 14 | // JSONObject obj = mInfo.toJson(); 15 | // obj.put("taskName", ApmTask.TASK_NET); 16 | // OutputProxy.output(msg, obj.toString()); 17 | // } catch (JSONException e) { 18 | // e.printStackTrace(); 19 | // } 20 | // } 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/tasks/NetParseTask.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.tasks; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.core.IInfo; 5 | import com.argusapm.android.core.job.net.NetInfo; 6 | import com.argusapm.android.debug.output.OutputProxy; 7 | import com.argusapm.android.debug.utils.DebugFloatWindowUtls; 8 | 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | 13 | /** 14 | * 网络分析类 15 | * 16 | * @author ArgusAPM Team 17 | */ 18 | public class NetParseTask implements IParser { 19 | @Override 20 | public boolean parse(IInfo info) { 21 | if (info != null && info instanceof NetInfo) { 22 | NetInfo aInfo = (NetInfo) info; 23 | if (aInfo.statusCode != 200) { 24 | String msg = String.format("网络错误,状态码:", aInfo.statusCode); 25 | DebugFloatWindowUtls.sendBroadcast(aInfo); 26 | try { 27 | JSONObject obj = aInfo.toJson(); 28 | obj.put("taskName", ApmTask.TASK_NET); 29 | OutputProxy.output(msg, obj.toString()); 30 | } catch (JSONException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | return false; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/utils/DebugFloatWindowUtls.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.utils; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import com.argusapm.android.core.IInfo; 7 | import com.argusapm.android.core.Manager; 8 | import com.argusapm.android.debug.view.FloatWindowManager; 9 | import com.argusapm.android.utils.ProcessUtils; 10 | 11 | import java.util.Set; 12 | 13 | /** 14 | * Debug模式,悬浮窗工具 15 | * 16 | * @author ArgusAPM Team 17 | */ 18 | public class DebugFloatWindowUtls { 19 | /** 20 | * 发送Broadcast消息 21 | * 22 | * @param aInfo 23 | */ 24 | public static void sendBroadcast(IInfo aInfo) { 25 | sendBroadcast(aInfo, ""); 26 | } 27 | 28 | /** 29 | * 发送Broadcast消息 30 | * 31 | * @param aInfo 32 | */ 33 | public static void sendBroadcast(IInfo aInfo, String showText) { 34 | Intent intent = new Intent(); 35 | intent.setAction(Manager.getContext().getPackageName() + FloatWindowManager.SUB_FLOAT_WIN_RECEIVER_ACTION); 36 | Bundle bundle = new Bundle(); 37 | bundle.putSerializable("info", aInfo); 38 | bundle.putString("processName", ProcessUtils.getCurrentProcessName()); 39 | bundle.putString("showText", showText); 40 | intent.putExtras(bundle); 41 | Manager.getContext().sendBroadcast(intent); 42 | } 43 | 44 | /** 45 | * 根据进程简写名称,查找进程全名显示 46 | * 47 | * @param processName 48 | * @param processSet 49 | * @return 50 | */ 51 | public static String getRealProcessName(String processName, Set processSet) { 52 | boolean isChildProcess = processName.contains(":"); 53 | String realName = ""; 54 | for (String pn : processSet) { 55 | if (isChildProcess && pn.contains(processName)) { 56 | realName = pn; 57 | break; 58 | } else if ((!isChildProcess) && pn.contains(processName) && (pn.contains(":") == false)) { 59 | realName = pn; 60 | break; 61 | } 62 | } 63 | return realName; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/debug/view/component/CircleView.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.debug.view.component; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.view.View; 7 | 8 | /** 9 | * 圆圈View 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class CircleView extends View { 14 | private float mDipScale = 1; 15 | private Paint mTextP = new Paint(); 16 | private Paint mCirclePaint = new Paint(); 17 | 18 | private int verticalCenter; 19 | private int horizontalCenter; 20 | private int circleRadius; 21 | 22 | public CircleView(Context context, float dipScale) { 23 | super(context); 24 | mDipScale = dipScale; 25 | } 26 | 27 | @Override 28 | protected void onDraw(Canvas canvas) { 29 | super.onDraw(canvas); 30 | verticalCenter = getHeight() / 2; 31 | horizontalCenter = getWidth() / 2; 32 | circleRadius = getHeight() / 2 - (int) (2 * mDipScale); 33 | mCirclePaint.setAntiAlias(true); 34 | mCirclePaint.setColor(0xff29a600); 35 | mCirclePaint.setStyle(Paint.Style.STROKE); 36 | mCirclePaint.setStrokeWidth(2 * mDipScale); 37 | canvas.drawCircle(horizontalCenter, verticalCenter, circleRadius, mCirclePaint); 38 | mTextP.setColor(0xff29a600); 39 | mTextP.setStrokeWidth(2 * mDipScale); 40 | mTextP.setTextSize(8 * mDipScale); 41 | mTextP.setTextAlign(Paint.Align.CENTER); 42 | Paint.FontMetrics fontMetrics = mTextP.getFontMetrics(); 43 | int baseLineY = (int) (verticalCenter - fontMetrics.top / 2 - fontMetrics.bottom / 2); 44 | canvas.drawText("Apm", horizontalCenter, baseLineY, mTextP); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/helper/ApmDebugEnable.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.helper; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import com.argusapm.android.Env; 7 | import com.argusapm.android.api.ApmTask; 8 | import com.argusapm.android.core.Manager; 9 | import com.argusapm.android.utils.FileUtils; 10 | import com.argusapm.android.utils.LogX; 11 | 12 | import org.json.JSONException; 13 | import org.json.JSONObject; 14 | 15 | import java.io.File; 16 | import java.io.FileInputStream; 17 | import java.io.InputStream; 18 | 19 | /** 20 | * debug包APM本地开关控制类 21 | * 22 | * @author ArgusAPM Team 23 | */ 24 | public class ApmDebugEnable { 25 | public static final String SUB_TAG = "debug_enable"; 26 | 27 | private static JSONObject sDebugSwitchControl; 28 | private static String sDebugConfig; 29 | 30 | public static String load() { 31 | return load(ApmTask.APM_CONFIG_FILE); 32 | } 33 | 34 | private static String load(String fileName) { 35 | String name = Manager.getInstance().getBasePath() + File.separator + fileName; 36 | if (TextUtils.isEmpty(sDebugConfig)) { 37 | sDebugConfig = FileUtils.readFile(name); 38 | } 39 | if (!TextUtils.isEmpty(sDebugConfig)) { 40 | try { 41 | if (sDebugSwitchControl == null) { 42 | sDebugSwitchControl = new JSONObject(sDebugConfig); 43 | } 44 | } catch (JSONException e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | return sDebugConfig; 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/network/UploadConfig.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network; 2 | 3 | /** 4 | * ArgusAPM相关配置 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class UploadConfig { 9 | public static final long UPLOAD_INTERVAL = 1 * 60 * 60 * 1000; //数据上传时间间隔 10 | public static final long UPLOAD_MIN_INTERVAL = 5 * 60 * 1000; //数据上传最小时间间隔 11 | public static final int RETRY_COUNT = 3; //上传失败重试次数 12 | } 13 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/network/UploadInfoField.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.network; 2 | 3 | /** 4 | * 上传数据字段 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class UploadInfoField { 9 | public static final String KEY_MODE = "m"; //MODEL 机型信息 10 | public static final String KEY_MANUFACTURE = "mf"; //MANUFACTURER 厂商 11 | public static final String KEY_SDKINI = "s"; //SDK_INT SDK版本 12 | public static final String KEY_RELEASEVERSION = "rv"; //RELEASE 系统版本 13 | public static final String KEY_FRAME_VER = "fv";//主程序版本号 14 | public static final String KEY_APMID = "apmid"; 15 | public static final String KEY_APMVER = "apmver"; 16 | public static final String KEY_TIME = "t"; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/utils/AspectjUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.utils; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public class AspectjUtils { 7 | public static final String JOINPOINT_KIND_CALL_METHOD = "method-call"; 8 | public static final String JOINPOINT_KIND_EXECUTION_METHOD = "method-execution"; 9 | public static final String JOINPOINT_KIND_CALL_CONSTRUCTOR = "constructor-call"; 10 | public static final String JOINPOINT_KIND_EXECUTION_CONSTRUCTOR = "constructor-execution"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/utils/FloatWindowUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.utils; 2 | 3 | import android.os.Build; 4 | import android.view.WindowManager; 5 | 6 | /** 7 | * 悬浮窗口工具类 8 | * 9 | * @author ArgusAPM Team 10 | */ 11 | public class FloatWindowUtils { 12 | 13 | /** 14 | * 选择悬浮窗类型 15 | */ 16 | public static int getType() { 17 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) { 18 | //7.1.1以上需要动态申请TYPE_APPLICATION_OVERLAY权限 19 | return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 20 | } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) { 21 | //7.1.1 需要动态申请TYPE_SYSTEM_ALERT权限 22 | return WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 23 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 24 | return WindowManager.LayoutParams.TYPE_TOAST; 25 | } else { 26 | return WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/utils/LogX.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.utils; 2 | 3 | import android.util.Log; 4 | 5 | import com.argusapm.android.Env; 6 | import com.argusapm.android.debug.storage.TraceWriter; 7 | 8 | /** 9 | * 日志类 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class LogX { 14 | private static final String LOG_FORMATTER = "❖ %s/%s ❖ %s"; 15 | 16 | public static void d(String tag, String msg) { 17 | Log.d(tag, msg); 18 | } 19 | 20 | public static void d(String tag, String subTag, String msg) { 21 | Log.d(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 22 | } 23 | 24 | public static void w(String tag, String msg) { 25 | Log.w(tag, msg); 26 | } 27 | 28 | public static void w(String tag, String subTag, String msg) { 29 | Log.w(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 30 | } 31 | 32 | public static void i(String tag, String msg) { 33 | Log.i(tag, msg); 34 | } 35 | 36 | public static void i(String tag, String subTag, String msg) { 37 | Log.i(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 38 | } 39 | 40 | public static void e(String tag, String msg) { 41 | Log.e(tag, msg); 42 | } 43 | 44 | public static void e(String tag, String subTag, String msg) { 45 | Log.e(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 46 | } 47 | 48 | public static void trace(String tag, String subTag, String msg) { 49 | TraceWriter.log(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 50 | } 51 | 52 | public static void o(String tag, String subTag, String msg) { 53 | Log.d(tag, String.format(LOG_FORMATTER, ProcessUtils.getCurrentProcessName(), subTag, msg)); 54 | } 55 | 56 | public static void o(String msg) { 57 | Log.d(Env.TAG_O, msg); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/utils/ProcessUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.utils; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import java.io.FileInputStream; 7 | 8 | import static com.argusapm.android.Env.DEBUG; 9 | import static com.argusapm.android.Env.TAG; 10 | 11 | /** 12 | * @author ArgusAPM Team 13 | */ 14 | public class ProcessUtils { 15 | private static final String SUB_TAG = "ProcessUtils"; 16 | private static String sProcessName = null; 17 | 18 | /** 19 | * 返回当前的进程名 20 | * 21 | * @return 22 | */ 23 | public static String getCurrentProcessName() { 24 | if (TextUtils.isEmpty(sProcessName)) { 25 | sProcessName = getCurrentProcessNameInternal(); 26 | } 27 | return sProcessName; 28 | } 29 | 30 | private static String getCurrentProcessNameInternal() { 31 | FileInputStream in = null; 32 | try { 33 | String fn = "/proc/self/cmdline"; 34 | in = new FileInputStream(fn); 35 | byte[] buffer = new byte[256]; 36 | int len = 0; 37 | int b; 38 | while ((b = in.read()) > 0 && len < buffer.length) { 39 | buffer[len++] = (byte) b; 40 | } 41 | if (len > 0) { 42 | String s = new String(buffer, 0, len, "UTF-8"); 43 | return s; 44 | } 45 | } catch (Throwable e) { 46 | if (DEBUG) { 47 | LogX.d(TAG, SUB_TAG, "getCurrentProcessName: got exception: " + Log.getStackTraceString(e)); 48 | } 49 | } finally { 50 | if (in != null) { 51 | try { 52 | in.close(); 53 | } catch (Throwable e) { 54 | if (DEBUG) { 55 | LogX.d(TAG, SUB_TAG, "getCurrentProcessName: got exception: " + Log.getStackTraceString(e)); 56 | } 57 | } 58 | } 59 | } 60 | return null; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/java/com/argusapm/android/utils/RootHelper.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * @author ArgusAPM Team 9 | */ 10 | public class RootHelper { 11 | 12 | public static boolean isRooted() { 13 | return isCmdExist("su"); 14 | } 15 | 16 | /** 17 | * 检查命令行 cmd 是否存在 18 | */ 19 | private static boolean isCmdExist(String cmd) { 20 | String path = System.getenv("PATH"); 21 | if (TextUtils.isEmpty(path)) { 22 | return false; 23 | } 24 | File file; 25 | if (path.contains(":")) { 26 | String[] array = path.split(":"); 27 | for (String str : array) { 28 | file = new File(str, cmd); 29 | if (file.exists()) { 30 | return true; 31 | } 32 | } 33 | return false; 34 | } else { 35 | // 可能 PATH 中只有一个路径 36 | file = new File(path, cmd); 37 | boolean ret = file.exists(); 38 | return ret; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #00000000 5 | 6 | 7 | #000000 8 | #4d4d4d 9 | #999999 10 | #b2b2b2 11 | #29a600 12 | #f14c0c 13 | #FFFFFF 14 | #0096FF 15 | #f79d1c 16 | 17 | 18 | @color/common_font_color_8 19 | #33000000 20 | 21 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18dp 4 | 10dp 5 | @dimen/dp_10 6 | 7 | 12dp 8 | 1dp 9 | 10 | 11 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-main/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | mobile 3 | com.apm.mobile 4 | 5 | 内存 6 | total: 7 | dalvik: 8 | native: 9 | other: 10 | M 11 | 12 | 帧率: 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/argus-apm-okhttp.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in ./sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -keep class com.argusapm.android.okhttp3.NetWorkInterceptor { *;} 27 | -keep class com.argusapm.android.okhttp3.OkHttpUtils { *;} 28 | #keep OkHttpClient及OkHttpClient的Builder内部类 29 | -keepattributes Exceptions,InnerClasses,... 30 | -keep class okhttp3.OkHttpClient{ 31 | *; 32 | } 33 | -keep class okhttp3.OkHttpClient$Builder { 34 | *; 35 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | -keep class com.argusapm.android.okhttp3.NetWorkInterceptor { *;} 28 | -keep class com.argusapm.android.okhttp3.OkHttpUtils { *;} -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/java/com/argusapm/android/okhttp3/DataRecordUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.okhttp3; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import com.argusapm.android.core.job.net.i.QOKHttp; 7 | 8 | /** 9 | * 具体实现逻辑,位于mobile module中 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class DataRecordUtils { 14 | 15 | /** 16 | * recordUrlRequest 17 | * 18 | * @param okHttpData 19 | */ 20 | public static void recordUrlRequest(OkHttpData okHttpData) { 21 | if (okHttpData == null || TextUtils.isEmpty(okHttpData.url)) { 22 | return; 23 | } 24 | 25 | QOKHttp.recordUrlRequest(okHttpData.url, okHttpData.code, okHttpData.requestSize, 26 | okHttpData.responseSize, okHttpData.startTime, okHttpData.costTime); 27 | 28 | if (Env.DEBUG) { 29 | Log.d(Env.TAG, "存储okkHttp请求数据,结束。"); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/java/com/argusapm/android/okhttp3/Env.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.okhttp3; 2 | 3 | /** 4 | * @author ArgusAPM Team 5 | */ 6 | public class Env { 7 | 8 | /** 9 | * the tag 10 | */ 11 | public static final String TAG = "NetWorkInterceptor"; 12 | 13 | public static final boolean DEBUG = false; 14 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/java/com/argusapm/android/okhttp3/OkHttp3Aspect.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.okhttp3; 2 | 3 | import com.argusapm.android.api.ApmTask; 4 | import com.argusapm.android.api.Client; 5 | 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | 11 | import okhttp3.OkHttpClient; 12 | 13 | /** 14 | * OKHTTP3切面文件 15 | * 16 | * @author ArgusAPM Team 17 | */ 18 | @Aspect 19 | public class OkHttp3Aspect { 20 | 21 | @Pointcut("call(public okhttp3.OkHttpClient build())") 22 | public void build() { 23 | 24 | } 25 | 26 | @Around("build()") 27 | public Object aroundBuild(ProceedingJoinPoint joinPoint) throws Throwable { 28 | Object target = joinPoint.getTarget(); 29 | 30 | if (target instanceof OkHttpClient.Builder && Client.isTaskRunning(ApmTask.TASK_NET)) { 31 | OkHttpClient.Builder builder = (OkHttpClient.Builder) target; 32 | builder.addInterceptor(new NetWorkInterceptor()); 33 | } 34 | 35 | return joinPoint.proceed(); 36 | } 37 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/java/com/argusapm/android/okhttp3/OkHttpData.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.okhttp3; 2 | 3 | /** 4 | * OKHTTP数据采集字段 5 | * 6 | * @author ArgusAPM Team 7 | */ 8 | public class OkHttpData { 9 | 10 | public String url; 11 | public long requestSize; 12 | public long responseSize; 13 | 14 | public long startTime; 15 | public long costTime; 16 | 17 | public int code; 18 | 19 | @Override 20 | public String toString() { 21 | return "OkHttpData{" + 22 | "url='" + url + '\'' + 23 | ", requestSize=" + requestSize + 24 | ", responseSize=" + responseSize + 25 | ", startTime=" + startTime + 26 | ", costTime=" + costTime + 27 | ", code=" + code + 28 | '}'; 29 | } 30 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/java/com/argusapm/android/okhttp3/OkHttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.android.okhttp3; 2 | 3 | import java.util.List; 4 | 5 | import okhttp3.Interceptor; 6 | 7 | /** 8 | * 协助ASM进行代码织入 9 | * 10 | * @author ArgusAPM Team 11 | */ 12 | public class OkHttpUtils { 13 | public static void insertToOkHttpClientBuilder(List interceptors) { 14 | try { 15 | boolean hasAddNetWorkInterceptor = false; 16 | for (Interceptor interceptor : interceptors) { 17 | if (interceptor instanceof NetWorkInterceptor) { 18 | hasAddNetWorkInterceptor = true; 19 | break; 20 | } 21 | } 22 | if (!hasAddNetWorkInterceptor) { 23 | interceptors.add(new NetWorkInterceptor()); 24 | } 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-okhttp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | OkHttp3Aspect 3 | 4 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/argusapm.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'argusapm'//aspectj的gradle插件名称,启用该插件 2 | argusApmAjxConfig { 3 | excludeJar 'okhttp', 'okio' 4 | // debugDependencies 'com.qihoo360.argusapm:argus-apm-main:1.3.43', 'com.qihoo360.argusapm:argus-apm-okhttp:2.0.0.1001', 'com.qihoo360.argusapm:argus-apm-aop:2.0.0.1001' 5 | //本地模块依赖,方便Debug调试 6 | // moduleDependencies ':argus-apm-main' 7 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply from: 'argusapm.gradle' 4 | 5 | android { 6 | useLibrary 'org.apache.http.legacy' 7 | compileSdkVersion 27 8 | 9 | buildToolsVersion "27.0.3" 10 | 11 | defaultConfig { 12 | applicationId "com.apm.application" 13 | minSdkVersion 15 14 | targetSdkVersion 27 15 | versionCode 1 16 | versionName "1.0" 17 | } 18 | buildTypes { 19 | debug { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | lintOptions { 29 | abortOnError false 30 | } 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_7 33 | targetCompatibility JavaVersion.VERSION_1_7 34 | } 35 | } 36 | 37 | dependencies { 38 | compile fileTree(include: ['*.jar'], dir: 'libs') 39 | compile 'com.squareup.okhttp3:okhttp:3.10.0' 40 | } 41 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Coding\Env\AndroidSdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -keep class com.apm.application.aop.** {*;} 19 | ######################## okhttp keep start####### ########################################### 20 | -dontwarn okhttp3.** 21 | -dontwarn okio.** 22 | -dontwarn javax.annotation.** 23 | -dontwarn org.conscrypt.** 24 | # A resource is loaded with a relative path so the package of this class must be preserved. 25 | -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase 26 | ############## -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/assets/demotest.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm/argus-apm-sample/src/main/assets/demotest.exe -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/ArgusAPMApplication.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.text.TextUtils; 6 | 7 | import com.argusapm.android.api.ApmTask; 8 | import com.argusapm.android.api.Client; 9 | import com.argusapm.android.core.Config; 10 | import com.argusapm.android.network.cloudrule.RuleSyncRequest; 11 | import com.argusapm.android.network.upload.CollectDataSyncUpload; 12 | import com.argusapm.sample.utils.ProcessUtils; 13 | 14 | /** 15 | * 自定义Application页面,方便ArgusAPM的初始化 16 | * 17 | * @author ArgusAPM Team 18 | */ 19 | public class ArgusAPMApplication extends Application { 20 | @Override 21 | protected void attachBaseContext(Context base) { 22 | super.attachBaseContext(base); 23 | boolean isUi = TextUtils.equals(getPackageName(), ProcessUtils.getCurrentProcessName()); 24 | Config.ConfigBuilder builder = new Config.ConfigBuilder() 25 | .setAppContext(this) 26 | .setRuleRequest(new RuleSyncRequest()) 27 | .setUpload(new CollectDataSyncUpload()) 28 | .setAppName("apm_demo") 29 | .setAppVersion("1.0.0") 30 | .setApmid("apm_demo");//该ID是在APM的后台进行申请的 31 | 32 | //单进程应用可忽略builder.setDisabled相关配置。 33 | if (!isUi) { //除了“主进程”,其他进程不需要进行数据上报、清理等逻辑。“主进程”通常为常驻进行,如果无常驻进程,即为UI进程。 34 | builder.setDisabled(ApmTask.FLAG_DATA_CLEAN) 35 | .setDisabled(ApmTask.FLAG_CLOUD_UPDATE) 36 | .setDisabled(ApmTask.FLAG_DATA_UPLOAD) 37 | .setDisabled(ApmTask.FLAG_COLLECT_ANR) 38 | .setDisabled(ApmTask.FLAG_COLLECT_FILE_INFO); 39 | } 40 | //builder.setEnabled(ApmTask.FLAG_COLLECT_ACTIVITY_AOP); //activity采用aop方案时打开,默认关闭即可。 41 | builder.setEnabled(ApmTask.FLAG_LOCAL_DEBUG); //是否读取本地配置,默认关闭即可。 42 | Client.attach(builder.build()); 43 | Client.isDebugOpen(false);//设置成true的时候将会打开悬浮窗 44 | Client.startWork(); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/test/TestActivity.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample.test; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import com.argusapm.sample.R; 7 | 8 | /** 9 | * Activity测试类 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class TestActivity extends Activity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_test); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/test/TestBlockActivity.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample.test; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import com.argusapm.sample.R; 7 | 8 | /** 9 | * Block测试页面 10 | * 11 | * @author ArgusAPM Team 12 | */ 13 | public class TestBlockActivity extends Activity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | try { 19 | Thread.sleep(5000); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | setContentView(R.layout.activity_test_block); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/test/TestUrlConnection.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample.test; 2 | 3 | import android.util.Log; 4 | 5 | import java.io.DataInputStream; 6 | import java.net.HttpURLConnection; 7 | import java.net.URL; 8 | 9 | /** 10 | * UrlConnection测试类 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class TestUrlConnection { 15 | private static final String TAG = "TestUrlConnection"; 16 | 17 | public static void urlConnectionRequest() { 18 | new Thread(new Runnable() { 19 | @Override 20 | public void run() { 21 | try { 22 | Log.d(TAG, "start urlConnectionRequest"); 23 | URL url = new URL("http://e.dangdang.com/media/api2.go?action=block&code=paymentSwitch&dang_name=dang_name&returnType=json&deviceType=Android&channelId=30066&clientVersionNo=5.9.5&serverVersionNo=1.2.1&permanentId=20170526065421752454273325035678487&deviceSerialNo=c817017a50b5b442a68c0ae46b83dfa1&macAddr=1c%3Acd%3Ae5%3A10%3A44%3A9d&resolution=720*1280&clientOs=5.1&platformSource=DDDS-P&channelType=&token="); 24 | HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(); 25 | httpUrlConnection.connect(); 26 | //返回打开连接读取的输入流 27 | DataInputStream dis = new DataInputStream(httpUrlConnection.getInputStream()); 28 | //判断是否正常响应数据 29 | if (httpUrlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { 30 | Log.d(TAG, "网络错误异常!!!!"); 31 | } 32 | Log.d(TAG, "end urlConnectionRequest end"); 33 | httpUrlConnection.disconnect(); 34 | } catch (Exception e) { 35 | Log.e(TAG, e.toString(), e.getCause()); 36 | } 37 | } 38 | }).start(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample.utils; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | 6 | import com.argusapm.android.api.ApmTask; 7 | 8 | import java.io.File; 9 | 10 | /** 11 | * 文件工具类 12 | * 13 | * @author ArgusAPM Team 14 | */ 15 | public class FileUtils { 16 | //因为在debug模式下,手动导入argus_apm_sdk_config.json至SD卡下的/360/Apm目录下 17 | public static String getSDArgusAPMConfigFilePath() { 18 | boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在 19 | if (!sdCardExist) { 20 | return ""; 21 | } 22 | File sdDir = Environment.getExternalStorageDirectory();//获取sd卡根目录 23 | return sdDir.toString() + "/360/Apm/argus_apm_sdk_config.json"; 24 | } 25 | 26 | public static boolean isContainApmConfigFileOfSdcard() { 27 | File file = new File(getSDArgusAPMConfigFilePath()); 28 | if (file.exists()) { 29 | return true; 30 | } else { 31 | return false; 32 | } 33 | } 34 | 35 | //该路径下的文件为网络上下载的云规则文件地址 36 | public static String getApmConfigFilePath(Context c) { 37 | String result = ""; 38 | if (c == null) { 39 | return result; 40 | } 41 | try { 42 | result = c.getFilesDir() + File.separator + ApmTask.APM_CONFIG_FILE; 43 | } catch (Exception e) { 44 | e.printStackTrace(); 45 | } 46 | return result; 47 | } 48 | 49 | public static boolean isDownloadApmConfigFileFromServer(Context context) { 50 | File file = new File(getApmConfigFilePath(context)); 51 | if (file.exists()) { 52 | return true; 53 | } else { 54 | return false; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/java/com/argusapm/sample/utils/ProcessUtils.java: -------------------------------------------------------------------------------- 1 | package com.argusapm.sample.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.FileInputStream; 6 | 7 | import static com.argusapm.sample.BuildConfig.DEBUG; 8 | 9 | /** 10 | * 进程工具类 11 | * 12 | * @author ArgusAPM Team 13 | */ 14 | public class ProcessUtils { 15 | private static final String SUB_TAG = "ProcessUtils"; 16 | private static String sProcessName = null; 17 | 18 | /** 19 | * 返回当前的进程名 20 | * 21 | * @return 22 | */ 23 | public static String getCurrentProcessName() { 24 | if (TextUtils.isEmpty(sProcessName)) { 25 | sProcessName = getCurrentProcessNameInternal(); 26 | } 27 | return sProcessName; 28 | } 29 | 30 | private static String getCurrentProcessNameInternal() { 31 | FileInputStream in = null; 32 | try { 33 | String fn = "/proc/self/cmdline"; 34 | in = new FileInputStream(fn); 35 | byte[] buffer = new byte[256]; 36 | int len = 0; 37 | int b; 38 | while ((b = in.read()) > 0 && len < buffer.length) { 39 | buffer[len++] = (byte) b; 40 | } 41 | if (len > 0) { 42 | String s = new String(buffer, 0, len, "UTF-8"); 43 | return s; 44 | } 45 | } catch (Throwable e) { 46 | 47 | } finally { 48 | if (in != null) { 49 | try { 50 | in.close(); 51 | } catch (Throwable e) { 52 | if (DEBUG) { 53 | } 54 | } 55 | } 56 | } 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/res/drawable/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/ArgusAPM/75ead19ca98a8a1f776688e9df5b572f20c80b12/argus-apm/argus-apm-sample/src/main/res/drawable/cloud.png -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/res/layout/activity_second.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/res/layout/activity_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/res/layout/activity_test_block.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /argus-apm/argus-apm-sample/src/main/res/layout/activity_test_ok_http3.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |