├── .gitignore ├── CONTRIBUTING.md ├── Example ├── Logan-Android │ ├── .gitignore │ ├── READMD-zh.md │ ├── README.md │ ├── app │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── test │ │ │ │ └── logan │ │ │ │ └── dianping │ │ │ │ └── com │ │ │ │ └── logan │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── gen │ │ │ │ └── test │ │ │ │ │ └── logan │ │ │ │ │ └── dianping │ │ │ │ │ └── com │ │ │ │ │ └── logan │ │ │ │ │ ├── BuildConfig.java │ │ │ │ │ ├── Manifest.java │ │ │ │ │ └── R.java │ │ │ ├── java │ │ │ │ └── test │ │ │ │ │ └── logan │ │ │ │ │ └── dianping │ │ │ │ │ └── com │ │ │ │ │ └── logan │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── MyApplication.java │ │ │ │ │ └── RealSendLogRunnable.java │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ └── activity_main.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 │ │ │ │ └── strings.xml │ │ │ └── test │ │ │ └── java │ │ │ └── test │ │ │ └── logan │ │ │ └── dianping │ │ │ └── com │ │ │ └── logan │ │ │ └── ExampleUnitTest.java │ ├── bintrayUpload.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── logan │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── dianping │ │ │ │ └── logan │ │ │ │ └── LoganTest.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── gen │ │ │ │ └── com │ │ │ │ │ └── dianping │ │ │ │ │ └── logan │ │ │ │ │ ├── BuildConfig.java │ │ │ │ │ ├── Manifest.java │ │ │ │ │ └── R.java │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── dianping │ │ │ │ │ └── logan │ │ │ │ │ ├── CLoganProtocol.java │ │ │ │ │ ├── ConstantCode.java │ │ │ │ │ ├── Logan.java │ │ │ │ │ ├── LoganConfig.java │ │ │ │ │ ├── LoganControlCenter.java │ │ │ │ │ ├── LoganModel.java │ │ │ │ │ ├── LoganProtocol.java │ │ │ │ │ ├── LoganProtocolHandler.java │ │ │ │ │ ├── LoganThread.java │ │ │ │ │ ├── OnLoganProtocolStatus.java │ │ │ │ │ ├── SendAction.java │ │ │ │ │ ├── SendLogCallback.java │ │ │ │ │ ├── SendLogDefaultRunnable.java │ │ │ │ │ ├── SendLogRunnable.java │ │ │ │ │ ├── Util.java │ │ │ │ │ └── WriteAction.java │ │ │ ├── jni │ │ │ │ ├── clogan_protocol.c │ │ │ │ └── clogan_protocol.h │ │ │ └── res │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── dianping │ │ │ └── logan │ │ │ └── ExampleUnitTest.java │ └── settings.gradle ├── Logan-NodeServer │ ├── .gitignore │ ├── README.md │ ├── app.ts │ ├── package.json │ ├── tsconfig.json │ └── yarn.lock ├── Logan-WebSDK │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── demo │ │ ├── js │ │ │ ├── report_log.00379bd039ba0d23e095.js │ │ │ ├── report_log.540408c7d6a5382cf118.js │ │ │ ├── test.js │ │ │ ├── vendors~encryption.b5564d7d68255d790409.js │ │ │ ├── vendors~encryption.ed2aadee96f4380db40e.js │ │ │ ├── vendors~report_log~save_log.1130f9f2be3cde3d0b2d.js │ │ │ ├── vendors~report_log~save_log.4f48e20a6aa09ee73148.js │ │ │ ├── vendors~save_log.81bc5a66cd212fb25cd1.js │ │ │ └── vendors~save_log.e6c9cfa9a3e7e0214368.js │ │ └── test.html │ ├── package.json │ ├── src │ │ └── test.js │ └── webpack.config.js ├── Logan-iOS │ ├── .gitignore │ ├── Logan-iOS.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Logan-iOS-Example.xcscheme │ ├── Logan-iOS │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── LGAppDelegate.h │ │ ├── LGAppDelegate.m │ │ ├── LGViewController.h │ │ ├── LGViewController.m │ │ ├── Logan-iOS-Info.plist │ │ ├── Logan-iOS-Prefix.pch │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ └── main.m │ ├── Podfile │ ├── Podfile.lock │ └── Tests │ │ ├── LoganTests.m │ │ ├── Tests-Info.plist │ │ ├── Tests-Prefix.pch │ │ ├── Tests.m │ │ └── en.lproj │ │ └── InfoPlist.strings └── Logan-macOS │ ├── Logan-macOS.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── Logan-macOS │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Info.plist │ ├── Logan-macOS.entitlements │ ├── Logan_macOS.entitlements │ └── main.m │ └── Logan-macOSTests │ ├── Info.plist │ └── Logan_macOSTests.m ├── Flutter ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android │ ├── .gitignore │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── build.gradle │ ├── gradle.properties │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── meituan │ │ └── flutter_logan │ │ ├── FlutterLoganPlugin.java │ │ ├── RealSendLogRunnable.java │ │ └── Utils.java ├── build.gradle ├── example │ ├── .flutter-plugins-dependencies │ ├── .gitignore │ ├── README.md │ ├── android │ │ ├── .project │ │ ├── .settings │ │ │ └── org.eclipse.buildship.core.prefs │ │ ├── app │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── meituan │ │ │ │ │ │ └── flutter_logan_example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res │ │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.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 │ │ │ │ │ └── styles.xml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── meituan │ │ │ │ └── flutter_logan_example │ │ │ │ └── FlutterLoganPluginTest.java │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ └── settings.gradle │ ├── ios │ │ ├── Flutter │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── flutter_export_environment.sh │ │ ├── Podfile │ │ ├── Runner copy-Info.plist │ │ ├── Runner copy2-Info.plist │ │ ├── Runner.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Runner │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Assets.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ │ └── LaunchImage.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ └── README.md │ │ │ ├── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── main.m │ │ ├── Test │ │ │ └── FlutterLoganTest.m │ │ └── flutter_logan_exampleTests │ │ │ ├── Info.plist │ │ │ └── flutter_logan_exampleTests.m │ ├── launch.json │ ├── lib │ │ └── main.dart │ ├── pubspec.lock │ ├── pubspec.yaml │ └── test │ │ └── widget_test.dart ├── flutter_01.log ├── flutter_logan.iml ├── ios │ ├── .gitignore │ ├── Assets │ │ └── .gitkeep │ ├── Classes │ │ ├── FlutterLoganPlugin.h │ │ └── FlutterLoganPlugin.m │ └── flutter_logan.podspec ├── lib │ └── flutter_logan.dart ├── local.properties ├── pubspec.lock ├── pubspec.yaml └── test │ └── flutter_logan_test.dart ├── LICENSE ├── Logan.podspec ├── Logan ├── Clogan │ ├── CMakeLists.txt │ ├── aes_util.c │ ├── aes_util.h │ ├── base_util.c │ ├── base_util.h │ ├── cJSON.c │ ├── cJSON.h │ ├── clogan_core.c │ ├── clogan_core.h │ ├── clogan_status.h │ ├── console_util.c │ ├── console_util.h │ ├── construct_data.c │ ├── construct_data.h │ ├── directory_util.c │ ├── directory_util.h │ ├── json_util.c │ ├── json_util.h │ ├── logan_config.h │ ├── main.c │ ├── main.dSYM │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── main │ ├── mmap_util.c │ ├── mmap_util.h │ ├── zlib_util.c │ └── zlib_util.h ├── LoganSite │ ├── .env.development.example │ ├── .gitignore │ ├── .npmrc │ ├── Dockerfile │ ├── README.md │ ├── README_CN.md │ ├── config │ │ ├── env.js │ │ ├── jest │ │ │ ├── cssTransform.js │ │ │ └── fileTransform.js │ │ ├── modules.js │ │ ├── paths.js │ │ ├── pnpTs.js │ │ ├── webpack.config.js │ │ └── webpackDevServer.config.js │ ├── docs │ │ ├── detail-page.png │ │ ├── index.png │ │ ├── list-page.png │ │ └── minimap.png │ ├── package.json │ ├── public │ │ ├── index.html │ │ ├── logan-favicon.png │ │ ├── manifest.json │ │ └── robots.txt │ ├── scripts │ │ ├── build.js │ │ ├── start.js │ │ └── test.js │ └── src │ │ ├── app.js │ │ ├── app.scss │ │ ├── common │ │ ├── adapter.js │ │ ├── adapter.test.js │ │ ├── api.js │ │ ├── color.js │ │ ├── color.test.js │ │ ├── components │ │ │ ├── ClickShare │ │ │ │ └── ClickShare.js │ │ │ └── Sider │ │ │ │ ├── Sider.js │ │ │ │ ├── new_logan_logo_white.png │ │ │ │ └── style.scss │ │ ├── time.js │ │ ├── time.test.js │ │ ├── util.js │ │ └── util.test.js │ │ ├── consts │ │ ├── logtypes.js │ │ ├── minimap-const.test.js │ │ ├── minimap.js │ │ └── pagination.js │ │ ├── index.js │ │ ├── store.js │ │ └── views │ │ ├── components │ │ ├── list-page │ │ │ ├── components │ │ │ │ └── header-bar │ │ │ │ │ ├── index.js │ │ │ │ │ └── style.scss │ │ │ ├── index.js │ │ │ └── style.scss │ │ └── log-detail-page │ │ │ ├── components │ │ │ ├── filter-bar │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── log-detail-card │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── log-information │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── loglist-infinite-scroll │ │ │ │ ├── consts.js │ │ │ │ ├── index.js │ │ │ │ └── style.module.scss │ │ │ └── time-minimap │ │ │ │ ├── index.js │ │ │ │ └── style.module.scss │ │ │ ├── index.js │ │ │ └── style.scss │ │ ├── native-list │ │ ├── index.js │ │ └── redux │ │ │ ├── action.js │ │ │ ├── initial-state.js │ │ │ └── reducer.js │ │ ├── native-log-detail │ │ ├── index.js │ │ └── redux │ │ │ ├── action.js │ │ │ ├── initial-state.js │ │ │ └── reducer.js │ │ ├── web-detail │ │ ├── index.js │ │ └── redux │ │ │ ├── action.js │ │ │ ├── initial-state.js │ │ │ └── reducer.js │ │ └── web-list │ │ ├── index.js │ │ └── redux │ │ ├── action.js │ │ ├── initial-state.js │ │ └── reducer.js ├── README ├── Server │ ├── Dockerfile │ ├── README │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── meituan │ │ │ └── logan │ │ │ └── web │ │ │ ├── controller │ │ │ ├── LoganController.java │ │ │ ├── LoganUploadController.java │ │ │ ├── WebLogController.java │ │ │ └── WebLogUploadController.java │ │ │ ├── dto │ │ │ ├── LoganLogDetailDTO.java │ │ │ ├── LoganTaskDTO.java │ │ │ ├── WebLogDetailDTO.java │ │ │ └── WebLogTaskDTO.java │ │ │ ├── enums │ │ │ ├── LogTypeEnum.java │ │ │ ├── PlatformEnum.java │ │ │ ├── ResultEnum.java │ │ │ ├── TaskStatusEnum.java │ │ │ └── WebLogFieldEnum.java │ │ │ ├── filter │ │ │ └── CORSFilter.java │ │ │ ├── handler │ │ │ ├── ContentHandler.java │ │ │ ├── LoganTypeOneHandler.java │ │ │ ├── LoganTypeThreeHandler.java │ │ │ ├── LoganTypeTwoHandler.java │ │ │ └── LoganTypeUnknownHandler.java │ │ │ ├── mapper │ │ │ ├── LoganLogDetailMapper.java │ │ │ ├── LoganTaskMapper.java │ │ │ ├── WebLogDetailMapper.java │ │ │ └── WebLogTaskMapper.java │ │ │ ├── model │ │ │ ├── LoganLogDetailModel.java │ │ │ ├── LoganLogItem.java │ │ │ ├── LoganLogSimpleModel.java │ │ │ ├── LoganTaskModel.java │ │ │ ├── Tuple.java │ │ │ ├── WebLogIndex.java │ │ │ ├── WebLogTaskModel.java │ │ │ ├── request │ │ │ │ └── LoganTaskRequest.java │ │ │ └── response │ │ │ │ └── LoganResponse.java │ │ │ ├── parser │ │ │ ├── LegacyLoganProtocol.java │ │ │ ├── LoganProtocol.java │ │ │ ├── RequestContextParser.java │ │ │ ├── WebLogDecryptHelper.java │ │ │ └── WebLogParser.java │ │ │ ├── service │ │ │ ├── BatchInsertService.java │ │ │ ├── HandlerDispatcher.java │ │ │ ├── LoganLogDetailService.java │ │ │ ├── LoganLogFileService.java │ │ │ ├── LoganTaskService.java │ │ │ ├── WebLogDetailService.java │ │ │ ├── WebTaskService.java │ │ │ └── impl │ │ │ │ ├── AbstractBatchInsertService.java │ │ │ │ ├── HandlerDispatcherDefaultImpl.java │ │ │ │ ├── LoganLogDetailServiceImpl.java │ │ │ │ ├── LoganLogFileServiceDefaultImpl.java │ │ │ │ ├── LoganTaskServiceImpl.java │ │ │ │ ├── WebLogDetailServiceImpl.java │ │ │ │ └── WebTaskServiceImpl.java │ │ │ ├── task │ │ │ ├── DelaySupplier.java │ │ │ ├── SingleThreadTaskLoop.java │ │ │ ├── Task.java │ │ │ └── TaskLoop.java │ │ │ └── util │ │ │ ├── DateFormatStyleEnum.java │ │ │ ├── DateTimeUtil.java │ │ │ ├── FileUtil.java │ │ │ ├── LocalStringUtils.java │ │ │ ├── OrderUtil.java │ │ │ ├── Threads.java │ │ │ ├── TrimFieldEnum.java │ │ │ └── TypeSafeUtil.java │ │ ├── resources │ │ ├── db.properties │ │ ├── log4j.properties │ │ ├── secure.properties │ │ └── sqlmap │ │ │ ├── LoganLogDetailMapper.xml │ │ │ ├── LoganTaskMapper.xml │ │ │ ├── WebLogDetailMapper.xml │ │ │ └── WebLogTaskMapper.xml │ │ └── webapp │ │ ├── WEB-INF │ │ ├── mvc-dispatcher-servlet.xml │ │ └── web.xml │ │ └── index.jsp ├── WebSDK │ ├── .eslintignore │ ├── .eslintrc.json │ ├── .gitignore │ ├── .npmrc │ ├── CHANGELOG.md │ ├── README.ch.md │ ├── README.md │ ├── demo │ │ ├── index.html │ │ └── js │ │ │ ├── encryption.69da1b4196dea19476ad.js │ │ │ ├── logan-web.js │ │ │ ├── report_log.ca98ffb54f24ea11895c.js │ │ │ ├── save_log.f31619128ca90313e1f9.js │ │ │ ├── vendors~encryption.bc757041a5d812f49350.js │ │ │ └── vendors~report_log~save_log.5fae2b4c3181d2c15df6.js │ ├── img │ │ ├── logan_web_structure.png │ │ ├── logan_web_structure_en.png │ │ ├── logan_web_workflow.png │ │ └── logan_web_workflow_en.png │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── global-config.ts │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── lib │ │ │ ├── ajax.ts │ │ │ ├── encryption.ts │ │ │ ├── js-encrypt.js │ │ │ ├── logan-db.ts │ │ │ ├── utils.ts │ │ │ └── xhr.ts │ │ ├── log-manager.ts │ │ ├── logan-operation-queue.ts │ │ ├── node-index.ts │ │ ├── report-log.ts │ │ └── save-log.ts │ ├── tests │ │ └── logan.test.ts │ ├── tsconfig.json │ └── webpack.config.js ├── clogan.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── deploy.sh ├── docker-compose.yaml ├── iOS │ ├── Logan.h │ ├── Logan.m │ ├── README-zh.md │ └── README.md ├── mbedtls │ ├── include │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ └── mbedtls │ │ │ ├── aes.h │ │ │ ├── aesni.h │ │ │ ├── arc4.h │ │ │ ├── asn1.h │ │ │ ├── asn1write.h │ │ │ ├── base64.h │ │ │ ├── bignum.h │ │ │ ├── blowfish.h │ │ │ ├── bn_mul.h │ │ │ ├── camellia.h │ │ │ ├── ccm.h │ │ │ ├── certs.h │ │ │ ├── check_config.h │ │ │ ├── cipher.h │ │ │ ├── cipher_internal.h │ │ │ ├── cmac.h │ │ │ ├── compat-1.3.h │ │ │ ├── config.h │ │ │ ├── ctr_drbg.h │ │ │ ├── debug.h │ │ │ ├── des.h │ │ │ ├── dhm.h │ │ │ ├── ecdh.h │ │ │ ├── ecdsa.h │ │ │ ├── ecjpake.h │ │ │ ├── ecp.h │ │ │ ├── ecp_internal.h │ │ │ ├── entropy.h │ │ │ ├── entropy_poll.h │ │ │ ├── error.h │ │ │ ├── gcm.h │ │ │ ├── havege.h │ │ │ ├── hmac_drbg.h │ │ │ ├── md.h │ │ │ ├── md2.h │ │ │ ├── md4.h │ │ │ ├── md5.h │ │ │ ├── md_internal.h │ │ │ ├── memory_buffer_alloc.h │ │ │ ├── net.h │ │ │ ├── net_sockets.h │ │ │ ├── oid.h │ │ │ ├── padlock.h │ │ │ ├── pem.h │ │ │ ├── pk.h │ │ │ ├── pk_internal.h │ │ │ ├── pkcs11.h │ │ │ ├── pkcs12.h │ │ │ ├── pkcs5.h │ │ │ ├── platform.h │ │ │ ├── platform_time.h │ │ │ ├── ripemd160.h │ │ │ ├── rsa.h │ │ │ ├── sha1.h │ │ │ ├── sha256.h │ │ │ ├── sha512.h │ │ │ ├── ssl.h │ │ │ ├── ssl_cache.h │ │ │ ├── ssl_ciphersuites.h │ │ │ ├── ssl_cookie.h │ │ │ ├── ssl_internal.h │ │ │ ├── ssl_ticket.h │ │ │ ├── threading.h │ │ │ ├── timing.h │ │ │ ├── version.h │ │ │ ├── x509.h │ │ │ ├── x509_crl.h │ │ │ ├── x509_crt.h │ │ │ ├── x509_csr.h │ │ │ └── xtea.h │ └── library │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── Makefile │ │ ├── aes.c │ │ ├── aesni.c │ │ ├── arc4.c │ │ ├── asn1parse.c │ │ ├── asn1write.c │ │ ├── base64.c │ │ ├── bignum.c │ │ ├── blowfish.c │ │ ├── camellia.c │ │ ├── ccm.c │ │ ├── certs.c │ │ ├── cipher.c │ │ ├── cipher_wrap.c │ │ ├── cmac.c │ │ ├── ctr_drbg.c │ │ ├── debug.c │ │ ├── des.c │ │ ├── dhm.c │ │ ├── ecdh.c │ │ ├── ecdsa.c │ │ ├── ecjpake.c │ │ ├── ecp.c │ │ ├── ecp_curves.c │ │ ├── entropy.c │ │ ├── entropy_poll.c │ │ ├── error.c │ │ ├── gcm.c │ │ ├── havege.c │ │ ├── hmac_drbg.c │ │ ├── md.c │ │ ├── md2.c │ │ ├── md4.c │ │ ├── md5.c │ │ ├── md_wrap.c │ │ ├── memory_buffer_alloc.c │ │ ├── net_sockets.c │ │ ├── oid.c │ │ ├── padlock.c │ │ ├── pem.c │ │ ├── pk.c │ │ ├── pk_wrap.c │ │ ├── pkcs11.c │ │ ├── pkcs12.c │ │ ├── pkcs5.c │ │ ├── pkparse.c │ │ ├── pkwrite.c │ │ ├── platform.c │ │ ├── ripemd160.c │ │ ├── rsa.c │ │ ├── sha1.c │ │ ├── sha256.c │ │ ├── sha512.c │ │ ├── ssl_cache.c │ │ ├── ssl_ciphersuites.c │ │ ├── ssl_cli.c │ │ ├── ssl_cookie.c │ │ ├── ssl_srv.c │ │ ├── ssl_ticket.c │ │ ├── ssl_tls.c │ │ ├── threading.c │ │ ├── timing.c │ │ ├── version.c │ │ ├── version_features.c │ │ ├── x509.c │ │ ├── x509_create.c │ │ ├── x509_crl.c │ │ ├── x509_crt.c │ │ ├── x509_csr.c │ │ ├── x509write_crt.c │ │ ├── x509write_csr.c │ │ └── xtea.c └── scripts │ └── migration │ └── mysql │ ├── 1_init.down.sql │ └── 1_init.up.sql ├── Package.swift ├── README-zh.md ├── README.md └── img ├── before_logan.png ├── logan_arch.png ├── logan_arch_paltform.png ├── logan_case.png ├── logan_detail.gif ├── logan_list_filter.gif ├── logan_logo.png ├── logan_process.png └── logan_system.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | clogan/cmake-build-debug 25 | 26 | **/.idea/* 27 | **/node_modules/* 28 | 29 | Carthage 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | .data/ 39 | 40 | # SwiftPM 41 | .swiftpm 42 | .build 43 | -------------------------------------------------------------------------------- /Example/Logan-Android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "test.logan.dianping.com.logan" 8 | minSdkVersion 14 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled true 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | testCompile 'junit:junit:4.12' 28 | compile project(':logan') 29 | // compile 'com.dianping.android.sdk:logan:1.1.0' 30 | // releaseCompile project(path: ':logan', configuration: 'release') 31 | // debugCompile project(path: ':logan', configuration: 'debug') 32 | } 33 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/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 /Users/baitian0521/Library/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 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/androidTest/java/test/logan/dianping/com/logan/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package test.logan.dianping.com.logan; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import android.content.Context; 6 | import android.support.test.InstrumentationRegistry; 7 | import android.support.test.runner.AndroidJUnit4; 8 | 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("test.logan.dianping.com.logan", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/gen/test/logan/dianping/com/logan/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package test.logan.dianping.com.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/gen/test/logan/dianping/com/logan/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package test.logan.dianping.com.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/gen/test/logan/dianping/com/logan/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package test.logan.dianping.com.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/java/test/logan/dianping/com/logan/MyApplication.java: -------------------------------------------------------------------------------- 1 | package test.logan.dianping.com.logan; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.dianping.logan.Logan; 7 | import com.dianping.logan.LoganConfig; 8 | import com.dianping.logan.OnLoganProtocolStatus; 9 | 10 | import java.io.File; 11 | 12 | public class MyApplication extends Application { 13 | 14 | private static final String TAG = MyApplication.class.getName(); 15 | private static final String FILE_NAME = "logan_v1"; 16 | 17 | @Override 18 | public void onCreate() { 19 | super.onCreate(); 20 | initLogan(); 21 | Logan.w("MyApplication onCreate", 3); 22 | Logan.w("MyApplication onCreate", 3); 23 | Logan.w("MyApplication onCreate", 3); 24 | } 25 | 26 | private void initLogan() { 27 | LoganConfig config = new LoganConfig.Builder() 28 | .setCachePath(getApplicationContext().getFilesDir().getAbsolutePath()) 29 | .setPath(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() 30 | + File.separator + FILE_NAME) 31 | .setEncryptKey16("0123456789012345".getBytes()) 32 | .setEncryptIV16("0123456789012345".getBytes()) 33 | .build(); 34 | Logan.init(config); 35 | Logan.setDebug(true); 36 | Logan.setOnLoganProtocolStatus(new OnLoganProtocolStatus() { 37 | @Override 38 | public void loganProtocolStatus(String cmd, int code) { 39 | Log.d(TAG, "clogan > cmd : " + cmd + " | " + "code : " + code); 40 | } 41 | }); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Logan Demo 3 | 4 | -------------------------------------------------------------------------------- /Example/Logan-Android/app/src/test/java/test/logan/dianping/com/logan/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package test.logan.dianping.com.logan; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Example/Logan-Android/bintrayUpload.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | apply plugin: 'com.jfrog.bintray' 3 | group = groupId 4 | artifactId = artifactId 5 | version = versionCode 6 | 7 | def getPropertyFromLocalProperties(key) { 8 | File file = project.rootProject.file('local.properties') 9 | if (file.exists()) { 10 | Properties properties = new Properties() 11 | properties.load(file.newDataInputStream()) 12 | return properties.getProperty(key) 13 | } 14 | } 15 | 16 | def siteUrl = 'https://tech.meituan.com/Logan.html' 17 | def gitUrl = 'https://github.com/Meituan-Dianping/Logan' 18 | 19 | bintray { 20 | user = getPropertyFromLocalProperties("bintray.user") 21 | key = getPropertyFromLocalProperties("bintray.apikey") 22 | configurations = ['archives'] 23 | pkg { 24 | repo = 'maven' 25 | name = "${project.group}:${project.name}" 26 | userOrg = 'dianping' 27 | licenses = ['MIT'] 28 | websiteUrl = siteUrl 29 | vcsUrl = gitUrl 30 | publish = true 31 | } 32 | } 33 | 34 | install { 35 | repositories.mavenInstaller { 36 | pom { 37 | project { 38 | packaging 'aar' 39 | groupId groupId 40 | artifactId artifactId 41 | version versionCode 42 | } 43 | } 44 | } 45 | } 46 | 47 | task sourcesJar(type: Jar) { 48 | from android.sourceSets.main.java.srcDirs 49 | classifier = 'sources' 50 | } 51 | 52 | artifacts { 53 | archives sourcesJar 54 | } -------------------------------------------------------------------------------- /Example/Logan-Android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | maven { 7 | url 'https://maven.google.com/' 8 | name 'Google' 9 | } 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:2.3.3' 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 14 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' 15 | 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | jcenter() 24 | maven { 25 | url 'https://maven.google.com/' 26 | name 'Google' 27 | } 28 | } 29 | } 30 | 31 | task clean(type: Delete) { 32 | delete rootProject.buildDir 33 | } 34 | 35 | -------------------------------------------------------------------------------- /Example/Logan-Android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | groupId=com.dianping.android.sdk 19 | artifactId=logan 20 | versionCode=1.2.4 -------------------------------------------------------------------------------- /Example/Logan-Android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Example/Logan-Android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Example/Logan-Android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Aug 10 17:35:04 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | SET (CMAKE_C_FLAGS_DEBUG "-g") 4 | SET (CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") 5 | 6 | set(EXTERN_DIR ../../../Logan/Clogan) 7 | 8 | add_subdirectory(${EXTERN_DIR} clogan.out) 9 | 10 | include_directories(${EXTERN_DIR}) 11 | 12 | link_directories(clogan.out) 13 | 14 | 15 | find_library( # Sets the name of the path variable. 16 | log-lib 17 | 18 | # Specifies the name of the NDK library that 19 | # you want CMake to locate. 20 | log ) 21 | 22 | # Specifies libraries CMake should link to your target library. You 23 | # can link multiple libraries, such as libraries you define in this 24 | # build script, prebuilt third-party libraries, or system libraries. 25 | 26 | add_library(logan SHARED src/main/jni/clogan_protocol.c) 27 | target_link_libraries(logan ${log-lib} z clogan) 28 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply from: rootProject.file("bintrayUpload.gradle") 3 | 4 | android { 5 | // publishNonDefault true 6 | 7 | compileSdkVersion 23 8 | buildToolsVersion "25.0.2" 9 | 10 | defaultConfig { 11 | minSdkVersion 14 12 | targetSdkVersion 23 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | 18 | externalNativeBuild { 19 | cmake { 20 | arguments '-DBUILD_TESTING=OFF', '-DANDROID_TOOLCHAIN=gcc' 21 | cFlags "-std=c11" 22 | abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' 23 | } 24 | } 25 | } 26 | buildTypes { 27 | release { 28 | minifyEnabled false 29 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 30 | } 31 | debug { 32 | jniDebuggable true 33 | testCoverageEnabled true 34 | } 35 | } 36 | externalNativeBuild { 37 | cmake { 38 | path "CMakeLists.txt" 39 | } 40 | } 41 | } 42 | 43 | dependencies { 44 | compile fileTree(include: ['*.jar'], dir: 'libs') 45 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 46 | exclude group: 'com.android.support', module: 'support-annotations' 47 | }) 48 | testCompile 'junit:junit:4.12' 49 | } 50 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/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 /Users/baitian0521/Library/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 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/gen/com/dianping/logan/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.dianping.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/gen/com/dianping/logan/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.dianping.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/gen/com/dianping/logan/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.dianping.logan; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/java/com/dianping/logan/LoganProtocolHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package com.dianping.logan; 24 | 25 | public interface LoganProtocolHandler { 26 | 27 | void logan_flush(); 28 | 29 | void logan_write(int flag, String log, long local_time, String thread_name, 30 | long thread_id, boolean is_main); 31 | 32 | void logan_open(String file_name); 33 | 34 | void logan_init(String cache_path, String dir_path, int max_file, String encrypt_key_16, 35 | String encrypt_iv_16); 36 | 37 | void logan_debug(boolean debug); 38 | 39 | void setOnLoganProtocolStatus(OnLoganProtocolStatus listener); 40 | } 41 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/java/com/dianping/logan/OnLoganProtocolStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package com.dianping.logan; 24 | 25 | public interface OnLoganProtocolStatus { 26 | void loganProtocolStatus(String cmd, int code); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/java/com/dianping/logan/SendAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package com.dianping.logan; 24 | 25 | class SendAction { 26 | 27 | long fileSize; //文件大小 28 | 29 | String date; //日期 30 | 31 | String uploadPath; 32 | 33 | SendLogRunnable sendLogRunnable; 34 | 35 | boolean isValid() { 36 | boolean valid = false; 37 | if (sendLogRunnable != null) { 38 | valid = true; 39 | } else if (fileSize > 0) { 40 | valid = true; 41 | } 42 | return valid; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/java/com/dianping/logan/SendLogCallback.java: -------------------------------------------------------------------------------- 1 | package com.dianping.logan; 2 | 3 | /** 4 | * Create by luoheng on 2019-11-20. 5 | */ 6 | public interface SendLogCallback { 7 | /** 8 | * 日志上传结果回调方法. 9 | * 10 | * @param statusCode 对应http状态码. 11 | * @param data http返回的data. 12 | */ 13 | void onLogSendCompleted(int statusCode, byte[] data); 14 | } 15 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/java/com/dianping/logan/WriteAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package com.dianping.logan; 24 | 25 | import android.text.TextUtils; 26 | 27 | class WriteAction { 28 | 29 | String log; //日志 30 | 31 | boolean isMainThread; 32 | 33 | long threadId; 34 | 35 | String threadName = ""; 36 | 37 | long localTime; 38 | 39 | int flag; 40 | 41 | boolean isValid() { 42 | boolean valid = false; 43 | if (!TextUtils.isEmpty(log)) { 44 | valid = true; 45 | } 46 | return valid; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | logan 3 | 4 | -------------------------------------------------------------------------------- /Example/Logan-Android/logan/src/test/java/com/dianping/logan/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.dianping.logan; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Example/Logan-Android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':logan' 2 | -------------------------------------------------------------------------------- /Example/Logan-NodeServer/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /Example/Logan-NodeServer/README.md: -------------------------------------------------------------------------------- 1 | ### Logan-Web nodejs解码实践 2 | 3 | 4 | 5 | ##### 部署步骤 6 | 7 | 1. `yarn install` 8 | 9 | 2. `yarn run start` 10 | 11 | 12 | 13 | ##### 测试 14 | 15 | ```javascript 16 | import Logan from "logan-web"; 17 | 18 | (async () => { 19 | Logan.initConfig({ 20 | reportUrl: 'https://yourServerAddressToAcceptLogs', 21 | publicKey: '-----BEGIN PUBLIC KEY-----\n' + 22 | 'MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgG2m5VVtZ4mHml3FB9foDRpDW7Pw\n' + 23 | 'Foa+1eYN777rNmIdnmezQqHWIRVcnTRVjrgGt2ndP2cYT7MgmWpvr8IjgN0PZ6ng\n' + 24 | 'MmKYGpapMqkxsnS/6Q8UZO4PQNlnsK2hSPoIDeJcHxDvo6Nelg+mRHEpD6K+1FIq\n' + 25 | 'zvdwVPCcgK7UbZElAgMBAAE=\n' + 26 | '-----END PUBLIC KEY-----', 27 | errorHandler(e: any) { console.error(e); } 28 | }); 29 | const reportResult = await Logan.report({ 30 | reportUrl: 'http://localhost:9002', 31 | deviceId: 'LocalDeviceIdOrUnionId', 32 | fromDayString: '2020-05-01', 33 | toDayString: '2020-05-10', 34 | webSource: '', 35 | environment: '', 36 | customInfo: '' 37 | }); 38 | 39 | console.log(reportResult); 40 | })(); 41 | 42 | ``` 43 | -------------------------------------------------------------------------------- /Example/Logan-NodeServer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logan-node-example", 3 | "version": "1.0.0", 4 | "main": "app.ts", 5 | "author": "westinchen", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "./node_modules/.bin/ts-node ./app.ts" 9 | }, 10 | "dependencies": { 11 | "crypto-js": "^4.0.0", 12 | "express": "~4.16.1", 13 | "js-encrypt": "^2.3.4", 14 | "morgan": "^1.10.0" 15 | }, 16 | "devDependencies": { 17 | "@types/crypto-js": "^3.1.45", 18 | "@types/express": "^4.17.6", 19 | "@types/morgan": "^1.9.0", 20 | "@types/node": "^13.13.5", 21 | "ts-node": "^8.10.1", 22 | "typescript": "^3.8.3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Example/Logan-NodeServer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "commonjs", 5 | "allowJs": false, 6 | "strict": true, 7 | "noImplicitAny": true, 8 | "moduleResolution": "node", 9 | "allowSyntheticDefaultImports": true, 10 | "esModuleInterop": true, 11 | "forceConsistentCasingInFileNames": true 12 | } 13 | } -------------------------------------------------------------------------------- /Example/Logan-WebSDK/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | node_modules/ -------------------------------------------------------------------------------- /Example/Logan-WebSDK/.npmrc: -------------------------------------------------------------------------------- 1 | registry="https://registry.npmjs.org/" -------------------------------------------------------------------------------- /Example/Logan-WebSDK/README.md: -------------------------------------------------------------------------------- 1 | # Logan Web SDK Example 2 | Show how to use [logan-web](https://www.npmjs.com/package/logan-web) with [webpack](https://webpack.js.org/). -------------------------------------------------------------------------------- /Example/Logan-WebSDK/demo/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Logan Web Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Logan-WebSDK/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logan-web-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "demo": "rm -rf demo/js && webpack" 8 | }, 9 | "author": "sylvia", 10 | "license": "MIT", 11 | "dependencies": { 12 | "logan-web": "^1.0.3" 13 | }, 14 | "devDependencies": { 15 | "webpack": "^4.41.2", 16 | "webpack-cli": "^3.3.10", 17 | "serialize-javascript": "^2.1.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Example/Logan-WebSDK/src/test.js: -------------------------------------------------------------------------------- 1 | var Logan = require('logan-web'); 2 | Logan.initConfig({ 3 | /* Demo Key */ 4 | publicKey: 5 | '-----BEGIN PUBLIC KEY-----\n' + 6 | 'MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgG2m5VVtZ4mHml3FB9foDRpDW7Pw\n' + 7 | 'Foa+1eYN777rNmIdnmezQqHWIRVcnTRVjrgGt2ndP2cYT7MgmWpvr8IjgN0PZ6ng\n' + 8 | 'MmKYGpapMqkxsnS/6Q8UZO4PQNlnsK2hSPoIDeJcHxDvo6Nelg+mRHEpD6K+1FIq\n' + 9 | 'zvdwVPCcgK7UbZElAgMBAAE=\n' + 10 | '-----END PUBLIC KEY-----' 11 | }); 12 | function timeFormat2Day(date) { 13 | var Y = date.getFullYear(); 14 | var M = date.getMonth() + 1; 15 | var D = date.getDate(); 16 | return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D); 17 | } 18 | document.getElementById('log').onclick = log; 19 | document.getElementById('logWithEncryption').onclick = logWithEncryption; 20 | document.getElementById('report').onclick = report; 21 | 22 | function log() { 23 | Logan.log('Hello World!', 1); 24 | } 25 | 26 | function logWithEncryption() { 27 | Logan.logWithEncryption('Hello World!', 2); 28 | } 29 | 30 | function report() { 31 | var now = new Date(); 32 | var sevenDaysAgo = new Date(+now - 6 * 24 * 3600 * 1000); 33 | Logan.report({ 34 | reportUrl: 'https://yourServerAddressToAcceptLogs', 35 | deviceId: 'test-logan-web', 36 | fromDayString: timeFormat2Day(sevenDaysAgo), 37 | toDayString: timeFormat2Day(now), 38 | webSource: 'browser', 39 | environment: navigator.userAgent, 40 | customInfo: JSON.stringify({ userId: 123456, biz: 'Live Better' }) 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /Example/Logan-WebSDK/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | const DEMO_PATH = './demo'; 3 | const STATIC_JS = 'js'; 4 | const PUBLIC_PATH = './' + STATIC_JS + '/'; 5 | module.exports = [ 6 | { 7 | mode: 'production', 8 | entry: { 9 | 'test': ['./src/test.js'] 10 | }, 11 | output: { 12 | path: path.join(__dirname, DEMO_PATH, STATIC_JS), 13 | publicPath: PUBLIC_PATH, 14 | filename: '[name].js', 15 | chunkFilename: '[name].[chunkhash].js', 16 | }, 17 | resolve: { 18 | extensions: ['.js'] 19 | }, 20 | module: { 21 | rules: [] 22 | } 23 | } 24 | ]; 25 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS/LGAppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | @import UIKit; 24 | 25 | 26 | @interface LGAppDelegate : UIResponder 27 | 28 | @property (strong, nonatomic) UIWindow *window; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS/LGViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | @import UIKit; 24 | 25 | 26 | @interface LGViewController : UIViewController 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS/Logan-iOS-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Logan-iOS/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | @import UIKit; 24 | #import "LGAppDelegate.h" 25 | 26 | int main(int argc, char *argv[]) { 27 | @autoreleasepool { 28 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LGAppDelegate class])); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | use_frameworks! 3 | 4 | target 'Logan-iOS_Example' do 5 | # pod 'Logan', '~> 1.2.10' 6 | pod 'Logan', :path => '../../' 7 | end 8 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Logan (1.2.10): 3 | - Logan/mbedtls (= 1.2.10) 4 | - Logan/mbedtls (1.2.10) 5 | 6 | DEPENDENCIES: 7 | - Logan (from `../../`) 8 | 9 | EXTERNAL SOURCES: 10 | Logan: 11 | :path: "../../" 12 | 13 | SPEC CHECKSUMS: 14 | Logan: 88a7f8103c2ec6b1d505b219c30e9245c755bfc6 15 | 16 | PODFILE CHECKSUM: 3b2aeec4fb7e1a3bc90b4b0cc926eadaabe1b207 17 | 18 | COCOAPODS: 1.11.3 19 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | @import XCTest; 24 | 25 | 26 | @interface Tests : XCTestCase 27 | 28 | @end 29 | 30 | 31 | @implementation Tests 32 | 33 | - (void)setUp { 34 | [super setUp]; 35 | // Put setup code here. This method is called before the invocation of each test method in the class. 36 | } 37 | 38 | - (void)tearDown { 39 | // Put teardown code here. This method is called after the invocation of each test method in the class. 40 | [super tearDown]; 41 | } 42 | 43 | - (void)testExample { 44 | // XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Example/Logan-iOS/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #import 24 | 25 | @interface AppDelegate : NSObject 26 | 27 | 28 | @end 29 | 30 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 Chen Yihu. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/Logan-macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/Logan_macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOS/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #import 24 | 25 | int main(int argc, const char * argv[]) { 26 | return NSApplicationMain(argc, argv); 27 | } 28 | -------------------------------------------------------------------------------- /Example/Logan-macOS/Logan-macOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Flutter/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | -------------------------------------------------------------------------------- /Flutter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 美团点评 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Flutter/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /Flutter/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android_ 4 | Project android_ created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Flutter/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments= 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(5.4)) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home= 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /Flutter/android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.meituan.flutter_logan' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.2.1' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation 'com.dianping.android.sdk:logan:1.2.2' 38 | } 39 | -------------------------------------------------------------------------------- /Flutter/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /Flutter/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_logan' 2 | -------------------------------------------------------------------------------- /Flutter/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Flutter/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | -------------------------------------------------------------------------------- /Flutter/example/.flutter-plugins-dependencies: -------------------------------------------------------------------------------- 1 | {"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_logan","dependencies":[]}]} -------------------------------------------------------------------------------- /Flutter/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /Flutter/example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_logan_examle 2 | This is a demo shows how to use fultter_logan plugin in flutter. 3 | 4 | ## How to run this demo? 5 | You can use Visual Studio Code or Xcode to run this project. 6 | Xcode: 7 | cd ~/your path/flutter_logan/example 8 | flutter build ios (you shuld install flutter first) 9 | open ios/Runner.xcworkspace -------------------------------------------------------------------------------- /Flutter/example/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Flutter/example/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /Flutter/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/java/com/meituan/flutter_logan_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.meituan.flutter_logan_example; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Flutter/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /Flutter/example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /Flutter/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /Flutter/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /Flutter/example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /Flutter/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /Flutter/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /Flutter/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /Flutter/example/ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/Users/maxiaojun/Development/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/maxiaojun/codes/mobile/flutter_logan_opensorce/example" 5 | export "FLUTTER_TARGET=lib/main.dart" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios" 8 | export "FLUTTER_FRAMEWORK_DIR=/Users/maxiaojun/Development/flutter/bin/cache/artifacts/engine/ios" 9 | export "FLUTTER_BUILD_NAME=1.0.0" 10 | export "FLUTTER_BUILD_NUMBER=1" 11 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner copy-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_logan_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner copy2-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_logan_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_logan_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Flutter/example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Flutter/example/ios/flutter_logan_exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Flutter/example/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | 13 | ] 14 | } -------------------------------------------------------------------------------- /Flutter/example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_logan_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /Flutter/flutter_logan.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Flutter/ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /Flutter/ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Flutter/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /Flutter/ios/Classes/FlutterLoganPlugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #import 24 | @interface FlutterLoganPlugin : NSObject 25 | @end 26 | -------------------------------------------------------------------------------- /Flutter/ios/flutter_logan.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'flutter_logan' 6 | s.version = '0.0.1' 7 | s.summary = 'A new flutter plugin project.' 8 | s.description = <<-DESC 9 | A new flutter plugin project. 10 | DESC 11 | s.homepage = 'https://github.com/Meituan-Dianping/Logan/Futter' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'maxiaojun02@meituan.com' } 14 | s.source = { :git => 'https://github.com/Meituan-Dianping/Logan.git', :tag => s.version.to_s } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | s.dependency 'Logan','1.2.6' 19 | 20 | s.ios.deployment_target = '8.0' 21 | end 22 | 23 | -------------------------------------------------------------------------------- /Flutter/local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Thu Aug 29 19:22:51 CST 2019 8 | sdk.dir=/Users/maxiaojun/Library/Android/sdk 9 | -------------------------------------------------------------------------------- /Flutter/test/flutter_logan_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:flutter_logan/flutter_logan.dart'; 4 | 5 | void main() { 6 | const MethodChannel channel = MethodChannel('flutter_logan'); 7 | 8 | setUp(() { 9 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 10 | return '42'; 11 | }); 12 | }); 13 | 14 | tearDown(() { 15 | channel.setMockMethodCallHandler(null); 16 | }); 17 | 18 | test('getPlatformVersion', () async { 19 | expect(await FlutterLogan.platformVersion, '42'); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 美团点评 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logan.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Logan' 3 | s.version = '1.2.10' 4 | s.summary = 'Logan is a lightweight case logging system based on mobile platform.' 5 | 6 | s.homepage = 'https://github.com/Meituan-Dianping/Logan' 7 | s.license = { :type => 'MIT', :file => 'LICENSE' } 8 | s.author = { 'jiangteng' => 'jiangteng.cn@gmail.com', 'yxiangnan' => 'yxiangnan@gmail.com', 'maxiaojun' => 'xiaojun_ma@qq.com'} 9 | s.source = { :git => 'https://github.com/Meituan-Dianping/Logan.git', :tag => s.version.to_s } 10 | 11 | s.ios.deployment_target = '9.0' 12 | s.osx.deployment_target = '10.9' 13 | 14 | s.source_files = "Logan/iOS/*.{h,m}", "Logan/Clogan/*.{h,c}" 15 | s.public_header_files = "Logan/iOS/*.h" 16 | 17 | s.subspec 'mbedtls' do |mbedtls| 18 | mbedtls.source_files = "Logan/mbedtls/**/*.{h,c}" 19 | mbedtls.header_dir = 'mbedtls' 20 | mbedtls.private_header_files = "Logan/mbedtls/**/*.h" 21 | mbedtls.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "${PODS_ROOT}/Logan/Logan/**"} 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /Logan/Clogan/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(clogan) 4 | 5 | set(MBEDTSL_INCLUDE ../mbedtls/include) 6 | set(MBEDTSL_LIBRARY ../mbedtls/library) 7 | 8 | include_directories(${MBEDTSL_INCLUDE}) 9 | 10 | add_subdirectory(${MBEDTSL_LIBRARY} clogan.out) 11 | 12 | set(SOURCE_FILES 13 | clogan_core.c 14 | mmap_util.c mmap_util.c cJSON.c 15 | construct_data.c construct_data.c 16 | zlib_util.h zlib_util.c logan_config.h 17 | json_util.h json_util.c aes_util.h aes_util.c 18 | clogan_status.h 19 | directory_util.h directory_util.c base_util.h base_util.c console_util.h console_util.c) 20 | 21 | add_library (clogan ${SOURCE_FILES}) 22 | target_link_libraries(clogan mbedcrypto) 23 | target_link_libraries(clogan z) 24 | 25 | add_executable(clogan_runner main.c) 26 | target_link_libraries(clogan_runner clogan) 27 | -------------------------------------------------------------------------------- /Logan/Clogan/aes_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #include "aes_util.h" 24 | #include "mbedtls/aes.h" 25 | 26 | static unsigned char KEY[16] = {0}; 27 | static unsigned char IV[16] = {0}; 28 | 29 | void aes_encrypt_clogan(unsigned char *in, unsigned char *out, int length, unsigned char *iv) { 30 | mbedtls_aes_context context; 31 | mbedtls_aes_setkey_enc(&context, (unsigned char *) KEY, 128); 32 | mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_ENCRYPT, length, iv, in, out); //加密 33 | } 34 | 35 | void aes_init_key_iv(const char *key, const char *iv) { 36 | memcpy(KEY, key, 16); 37 | memcpy(IV, iv, 16); 38 | } 39 | 40 | void aes_inflate_iv_clogan(unsigned char *aes_iv) { 41 | memcpy(aes_iv, IV, 16); 42 | } 43 | -------------------------------------------------------------------------------- /Logan/Clogan/aes_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLOGAN_AES_UTIL_H 24 | #define CLOGAN_AES_UTIL_H 25 | 26 | #include 27 | 28 | void aes_encrypt_clogan(unsigned char *in, unsigned char *out, int length, unsigned char *iv); 29 | 30 | void aes_init_key_iv(const char *key, const char *iv); 31 | 32 | void aes_inflate_iv_clogan(unsigned char *aes_iv); 33 | 34 | #endif //CLOGAN_AES_UTIL_H 35 | -------------------------------------------------------------------------------- /Logan/Clogan/base_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLOGAN_BASE_UTIL_H 24 | #define CLOGAN_BASE_UTIL_H 25 | 26 | //获取时间毫秒 27 | long long get_system_current_clogan(void); 28 | 29 | //判断String是否为空 30 | int is_string_empty_clogan(char *item); 31 | 32 | /** 33 | * 检查CPU的字节序 34 | * @return 1,高字节序 2,低字节序 35 | */ 36 | int cpu_byteorder_clogan(void); 37 | 38 | /** 39 | * 调整字节序,默认传入的字节序为低字节序,如果系统为高字节序,转化为高字节序 40 | * c语言字节序的写入是低字节序的,读取默认也是低字节序的 41 | * java语言字节序默认是高字节序的 42 | * @param data 43 | */ 44 | void adjust_byteorder_clogan(char item[4]); 45 | 46 | #endif //CLOGAN_BASE_UTIL_H 47 | -------------------------------------------------------------------------------- /Logan/Clogan/console_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include "console_util.h" 26 | 27 | static int is_debug_logan = 0; 28 | 29 | int printf_clogan(char *fmt, ...) { 30 | int cnt = 0; 31 | if (is_debug_logan) { 32 | va_list argptr; 33 | va_start(argptr, fmt); 34 | cnt = vprintf(fmt, argptr); 35 | va_end(argptr); 36 | } 37 | return (cnt); 38 | } 39 | 40 | void set_debug_clogan(int debug) { 41 | is_debug_logan = debug; 42 | } 43 | -------------------------------------------------------------------------------- /Logan/Clogan/console_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLOGAN_DEMO_CONSOLE_H_H 24 | #define CLOGAN_DEMO_CONSOLE_H_H 25 | 26 | 27 | int printf_clogan(char *content, ...); 28 | 29 | void set_debug_clogan(int debug); 30 | 31 | #endif //CLOGAN_DEMO_CONSOLE_H_H 32 | -------------------------------------------------------------------------------- /Logan/Clogan/construct_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLOGAN_BUILD_DATA_H 24 | #define CLOGAN_BUILD_DATA_H 25 | 26 | typedef struct { 27 | char *data; 28 | int data_len; 29 | } Construct_Data_cLogan; 30 | 31 | Construct_Data_cLogan * 32 | construct_json_data_clogan(char *log, int flag, long long local_time, char *thread_name, 33 | long long thread_id, int is_main); 34 | 35 | void construct_data_delete_clogan(Construct_Data_cLogan *data); 36 | 37 | #endif //CLOGAN_BUILD_DATA_H 38 | -------------------------------------------------------------------------------- /Logan/Clogan/directory_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-present, 美团点评 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLOGAN_DIRECTORY_UTIL_H 24 | #define CLOGAN_DIRECTORY_UTIL_H 25 | 26 | int makedir_clogan(const char *path); 27 | 28 | int is_file_exist_clogan(const char *path); 29 | 30 | #endif //CLOGAN_DIRECTORY_UTIL_H 31 | -------------------------------------------------------------------------------- /Logan/Clogan/main.c: -------------------------------------------------------------------------------- 1 | #include "base_util.h" 2 | #include "clogan_core.h" 3 | #include 4 | #include 5 | 6 | int main(int argc, const char **argv) { 7 | char key[16] = "0123456789012345"; 8 | char iv[16] = "0123456789012345"; 9 | int code; 10 | 11 | clogan_debug(0); 12 | code = clogan_init("log", "log", 10 * 1024 * 1024, key, iv); 13 | printf("[init]: %d\n", code); 14 | 15 | code = clogan_open("logan.bin"); 16 | printf("[open]: %d\n", code); 17 | 18 | long long ts = get_system_current_clogan(); 19 | time_t now = time(NULL); 20 | char *now_str = ctime(&now); 21 | printf("[now]: %s\n", now_str); 22 | 23 | clogan_flush(); 24 | clogan_write(10, now_str, ts, "main", 1, 1); 25 | clogan_write(10, "[log 1]", ts++, "main", 1, 1); 26 | clogan_write(10, "[log 2]", ts++, "main", 1, 1); 27 | clogan_write(10, "[log 3]", ts++, "main", 1, 1); 28 | clogan_write(10, "[log 4]", ts++, "main", 1, 1); 29 | clogan_write(10, "[log 5]", ts++, "main", 1, 1); 30 | clogan_write(10, "how", ts++, "main", 1, 1); 31 | clogan_write(10, "are", ts++, "main", 1, 1); 32 | clogan_write(10, "you", ts++, "main", 1, 1); 33 | clogan_write(10, "fine", ts++, "main", 1, 1); 34 | // clogan_flush(); 35 | 36 | printf("[exit]\n"); 37 | } 38 | -------------------------------------------------------------------------------- /Logan/Clogan/main.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.main 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /Logan/Clogan/main.dSYM/Contents/Resources/DWARF/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/Clogan/main.dSYM/Contents/Resources/DWARF/main -------------------------------------------------------------------------------- /Logan/LoganSite/.env.development.example: -------------------------------------------------------------------------------- 1 | API_BASE_URL=http://127.0.0.1:8888/logan-web 2 | -------------------------------------------------------------------------------- /Logan/LoganSite/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | /deploy 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .env.development 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | /.idea 27 | 28 | /.vscode 29 | 30 | yarn.lock 31 | package-lock.json 32 | -------------------------------------------------------------------------------- /Logan/LoganSite/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ -------------------------------------------------------------------------------- /Logan/LoganSite/Dockerfile: -------------------------------------------------------------------------------- 1 | # build frontend 2 | FROM node:10-alpine as frontend 3 | 4 | WORKDIR /web 5 | COPY . . 6 | RUN yarn config set registry https://registry.npmmirror.com -g && \ 7 | yarn config set sass_binary_site "https://npmmirror.com/mirrors/node-sass/" -g && \ 8 | yarn && \ 9 | yarn build 10 | 11 | FROM library/nginx 12 | USER root 13 | 14 | # copy static files 15 | COPY --from=frontend /web/build/ /usr/share/nginx/html/ 16 | 17 | # HEALTHCHECK 18 | HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD service nginx status | grep running || exit 1 -------------------------------------------------------------------------------- /Logan/LoganSite/config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /Logan/LoganSite/config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const camelcase = require('camelcase'); 5 | 6 | // This is a custom Jest transformer turning file imports into filenames. 7 | // http://facebook.github.io/jest/docs/en/webpack.html 8 | 9 | module.exports = { 10 | process(src, filename) { 11 | const assetFilename = JSON.stringify(path.basename(filename)); 12 | 13 | if (filename.match(/\.svg$/)) { 14 | // Based on how SVGR generates a component name: 15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 16 | const pascalCaseFilename = camelcase(path.parse(filename).name, { 17 | pascalCase: true, 18 | }); 19 | const componentName = `Svg${pascalCaseFilename}`; 20 | return `const React = require('react'); 21 | module.exports = { 22 | __esModule: true, 23 | default: ${assetFilename}, 24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) { 25 | return { 26 | $$typeof: Symbol.for('react.element'), 27 | type: 'svg', 28 | ref: ref, 29 | key: null, 30 | props: Object.assign({}, props, { 31 | children: ${assetFilename} 32 | }) 33 | }; 34 | }), 35 | };`; 36 | } 37 | 38 | return `module.exports = ${assetFilename};`; 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /Logan/LoganSite/config/pnpTs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { resolveModuleName } = require('ts-pnp'); 4 | 5 | exports.resolveModuleName = ( 6 | typescript, 7 | moduleName, 8 | containingFile, 9 | compilerOptions, 10 | resolutionHost 11 | ) => { 12 | return resolveModuleName( 13 | moduleName, 14 | containingFile, 15 | compilerOptions, 16 | resolutionHost, 17 | typescript.resolveModuleName 18 | ); 19 | }; 20 | 21 | exports.resolveTypeReferenceDirective = ( 22 | typescript, 23 | moduleName, 24 | containingFile, 25 | compilerOptions, 26 | resolutionHost 27 | ) => { 28 | return resolveModuleName( 29 | moduleName, 30 | containingFile, 31 | compilerOptions, 32 | resolutionHost, 33 | typescript.resolveTypeReferenceDirective 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /Logan/LoganSite/docs/detail-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/docs/detail-page.png -------------------------------------------------------------------------------- /Logan/LoganSite/docs/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/docs/index.png -------------------------------------------------------------------------------- /Logan/LoganSite/docs/list-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/docs/list-page.png -------------------------------------------------------------------------------- /Logan/LoganSite/docs/minimap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/docs/minimap.png -------------------------------------------------------------------------------- /Logan/LoganSite/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Logan 11 | 12 | 13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /Logan/LoganSite/public/logan-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/public/logan-favicon.png -------------------------------------------------------------------------------- /Logan/LoganSite/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Logan", 3 | "name": "Logan", 4 | "icons": [ 5 | { 6 | "src": "logan-favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Logan/LoganSite/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /Logan/LoganSite/scripts/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'test'; 5 | process.env.NODE_ENV = 'test'; 6 | process.env.PUBLIC_URL = ''; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require('../config/env'); 17 | 18 | 19 | const jest = require('jest'); 20 | const execSync = require('child_process').execSync; 21 | let argv = process.argv.slice(2); 22 | 23 | function isInGitRepository() { 24 | try { 25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); 26 | return true; 27 | } catch (e) { 28 | return false; 29 | } 30 | } 31 | 32 | function isInMercurialRepository() { 33 | try { 34 | execSync('hg --cwd . root', { stdio: 'ignore' }); 35 | return true; 36 | } catch (e) { 37 | return false; 38 | } 39 | } 40 | 41 | // Watch unless on CI or explicitly running all tests 42 | if ( 43 | !process.env.CI && 44 | argv.indexOf('--watchAll') === -1 && 45 | argv.indexOf('--watchAll=false') === -1 46 | ) { 47 | // https://github.com/facebook/create-react-app/issues/5210 48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository(); 49 | argv.push(hasSourceControl ? '--watch' : '--watchAll'); 50 | } 51 | 52 | 53 | jest.run(argv); 54 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/app.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import {Switch, Route, Redirect} from "react-router-dom"; 3 | import { ConnectedRouter } from 'connected-react-router' 4 | import {Layout} from "antd"; 5 | import {history} from "./store"; 6 | import NativeList from "./views/native-list"; 7 | import NativeLogDetail from "./views/native-log-detail"; 8 | import WebList from "./views/web-list"; 9 | import WebLogDetail from "./views/web-detail"; 10 | import Sider from "./common/components/Sider/Sider"; 11 | import "antd/dist/antd.css"; 12 | import "./app.scss"; 13 | 14 | class App extends Component { 15 | 16 | componentDidCatch(error, errorInfo) { 17 | console.log(error); 18 | } 19 | 20 | render() { 21 | return ( 22 | 23 | <> 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 37 |
38 | ); 39 | } 40 | } 41 | 42 | export default App; 43 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/app.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | height: 100%; 5 | } 6 | 7 | #root { 8 | height: 100%; 9 | width: 100%; 10 | display: flex; 11 | } 12 | 13 | .ant-layout-sider { 14 | height: 100%; 15 | } 16 | 17 | .app { 18 | display: flex; 19 | flex: 1; 20 | height: 100%; 21 | } 22 | 23 | .ant-timeline-item-content { 24 | width: 100%; 25 | cursor: pointer; 26 | } 27 | 28 | .ant-collapse-item { 29 | border: none !important; 30 | 31 | .ant-collapse-header { 32 | font-size: 15px; 33 | padding: 6px 0 6px 40px; 34 | 35 | .arrow { 36 | line-height: 35px; 37 | } 38 | } 39 | 40 | .ant-collapse-content { 41 | padding: 0 24px 10px; 42 | position: relative; 43 | background-color: #f7f7f7 !important; 44 | z-index: 9; 45 | width: 100%; 46 | height: 270px; 47 | border: 0; 48 | 49 | .ant-collapse-content-box { 50 | background-color: #fff; 51 | height: 100%; 52 | padding: 10px 20px; 53 | word-break: break-all; 54 | overflow: auto; 55 | border: solid 1px #e1e1e1; 56 | } 57 | } 58 | } 59 | 60 | .ant-dropdown { 61 | background-color: #fff; 62 | box-shadow: rgba(0, 0, 0, 0.15) 0px 2px 8px; 63 | } 64 | 65 | .ant-dropdown-trigger { 66 | .anticon { 67 | font-size: 16px !important; 68 | } 69 | } 70 | 71 | .ant-checkbox-wrapper { 72 | display: flex; 73 | align-items: center; 74 | 75 | span:nth-child(2) { 76 | flex: 1 77 | } 78 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/adapter.js: -------------------------------------------------------------------------------- 1 | import {nativeLogTypeConfigs, webLogTypeConfigs} from "../consts/logtypes"; 2 | 3 | export const convertBriefsToMinimapBriefs = (briefs, type) => { 4 | let ret = []; 5 | const LogTypeRules = type === "native" ? nativeLogTypeConfigs : webLogTypeConfigs; 6 | for (let brief of briefs) { 7 | let logType = LogTypeRules.find(rule => rule.logType === brief.logType); 8 | if (logType === undefined) { 9 | logType = { 10 | logType: 0, 11 | logTypeName: "未知日志", 12 | displayColor: "#000000" 13 | }; 14 | } 15 | 16 | if (type === "native") { 17 | ret.push({ 18 | id: brief.id, 19 | time: brief.logTime, 20 | logType: { 21 | type: logType.logType, 22 | logTypeName: logType.logTypeName, 23 | displayColor: logType.displayColor 24 | } 25 | }); 26 | } else { 27 | ret.push({ 28 | id: brief.detailId, 29 | time: brief.logTime, 30 | logType: { 31 | type: logType.logType, 32 | logTypeName: logType.logTypeName, 33 | displayColor: logType.displayColor 34 | } 35 | }) 36 | } 37 | 38 | 39 | } 40 | return ret; 41 | }; 42 | 43 | export const convertBriefsToLoglistInfiniteScrollBriefs = (briefs, type) => { 44 | if (type === "native") { 45 | return briefs; 46 | } else { 47 | return briefs.map(item => ({ 48 | id: item.detailId, 49 | logTime: item.logTime, 50 | logType: item.logType 51 | })) 52 | } 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/adapter.test.js: -------------------------------------------------------------------------------- 1 | import {convertBriefsToMinimapBriefs} from "./adapter" 2 | 3 | describe("log type data adapter", () => { 4 | 5 | 6 | it("should return empty array when given empty brief", () => { 7 | const ret = convertBriefsToMinimapBriefs([], "native"); 8 | expect(ret).toEqual([]); 9 | }); 10 | 11 | it("should return proper native log type information", () => { 12 | const ret = convertBriefsToMinimapBriefs([{logType: 1, id: 1, logTime: 111111}], "native"); 13 | expect(ret).toEqual([{ 14 | id: 1, 15 | time: 111111, 16 | logType: { 17 | type: 1, 18 | logTypeName: "日志类型1", 19 | displayColor: "#32CD32" 20 | } 21 | }]); 22 | }); 23 | 24 | it("should return proper web log type information", () => { 25 | const ret = convertBriefsToMinimapBriefs([{logType: 1, id: 1, logTime: 111111}], "native"); 26 | expect(ret).toEqual([{ 27 | id: 1, 28 | time: 111111, 29 | logType: { 30 | type: 1, 31 | logTypeName: "日志类型1", 32 | displayColor: "#32CD32" 33 | } 34 | }]); 35 | }); 36 | 37 | it("should return unknown log type information", () => { 38 | const ret = convertBriefsToMinimapBriefs([{logType: 1, detailId: 1, logTime: 111111}], "web"); 39 | expect(ret).toEqual([{ 40 | id: 1, 41 | time: 111111, 42 | logType: { 43 | type: 1, 44 | logTypeName: "日志类型1", 45 | displayColor: "#32CD32" 46 | } 47 | }]); 48 | }) 49 | }); -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/color.js: -------------------------------------------------------------------------------- 1 | export const convertRgbToRgba = (rgb, a) => { 2 | let hex = rgb.replace(/^\s*#|\s*$/g, ""); 3 | if (hex.length === 3) { 4 | hex = hex.replace(/(.)/g, "$1$1"); 5 | } 6 | const r = parseInt(hex.substr(0, 2), 16); 7 | const g = parseInt(hex.substr(2, 2), 16); 8 | const b = parseInt(hex.substr(4, 2), 16); 9 | return `rgba(${r},${g},${b},${a})`; 10 | }; 11 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/color.test.js: -------------------------------------------------------------------------------- 1 | import {convertRgbToRgba} from "./color"; 2 | 3 | 4 | describe("Color Module", () => { 5 | describe("convertRgbToRgba function", () => { 6 | it("should process 3-character dash notation properly", () => { 7 | const expected = "rgba(255,255,255,0)"; 8 | const actual = convertRgbToRgba("#fff", 0); 9 | expect(actual).toBe(expected); 10 | }); 11 | 12 | it("should process 6-character dash notation properly", () => { 13 | const expected = "rgba(255,255,255,0)"; 14 | const actual = convertRgbToRgba("#ffffff", 0); 15 | expect(actual).toBe(expected); 16 | }); 17 | }) 18 | }) 19 | 20 | 21 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/components/ClickShare/ClickShare.js: -------------------------------------------------------------------------------- 1 | import "antd/dist/antd.css"; 2 | import React, { Component } from "react"; 3 | import { message, Button, Icon } from "antd"; 4 | import Clipboard from "clipboard"; 5 | let lastSuccTime = Date.now(); 6 | 7 | class ClickShare extends Component { 8 | state = { 9 | clipboard: null 10 | }; 11 | 12 | render() { 13 | const {buttonId, shareUrl, buttonStyle, icon, buttonText} = this.props; 14 | const defaultButtonStyle = { 15 | color: "#fff", 16 | backgroundColor: "#52c41a" 17 | } 18 | return ( 19 | 27 | ); 28 | } 29 | 30 | componentDidMount() { 31 | const clipboard = new Clipboard("#" + this.props.buttonId); 32 | clipboard.on("success", () => { 33 | if (Date.now() - lastSuccTime > 1000) { 34 | message.success("链接已复制到剪贴板", 2); 35 | lastSuccTime = Date.now(); 36 | } 37 | }); 38 | this.setState(clipboard); 39 | } 40 | 41 | componentWillUnmount() { 42 | this.state.clipboard && this.state.clipboard.destroy(); 43 | } 44 | } 45 | 46 | export default ClickShare; 47 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/components/Sider/new_logan_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/src/common/components/Sider/new_logan_logo_white.png -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/components/Sider/style.scss: -------------------------------------------------------------------------------- 1 | .sider-logo { 2 | background-image: url(new_logan_logo_white.png); 3 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/time.js: -------------------------------------------------------------------------------- 1 | var checkDate = date => { 2 | if (date === "Invalid Date") { 3 | throw new Error("Invalid Date"); 4 | } else { 5 | return true; 6 | } 7 | }; 8 | 9 | export const stringifyTime = (date, noMiniSec) => { 10 | checkDate(date); 11 | let H = date.getHours(); 12 | H = H < 10 ? "0" + H : H; 13 | let M = date.getMinutes(); 14 | M = M < 10 ? "0" + M : M; 15 | let S = date.getSeconds(); 16 | S = S < 10 ? "0" + S : S; 17 | let ss = date % 1000; 18 | return `${H}${":" + M}${":" + S}${noMiniSec ? "" : "." + ss}`; 19 | }; 20 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/time.test.js: -------------------------------------------------------------------------------- 1 | import {stringifyTime} from "./time"; 2 | 3 | 4 | describe("stringifyTime function", () => { 5 | it("should show milisecond", () => { 6 | const date = new Date(1573438103079); 7 | expect(stringifyTime(date, false)).toBe("10:08:23.79") 8 | }); 9 | 10 | it("shouldn't show milisecond", () => { 11 | const date = new Date(1573438103079); 12 | expect(stringifyTime(date, true)).toBe("10:08:23") 13 | }) 14 | }) -------------------------------------------------------------------------------- /Logan/LoganSite/src/common/util.js: -------------------------------------------------------------------------------- 1 | import {findIndex} from "lodash"; 2 | 3 | import {NUMBER_OF_LOG_IN_SINGLE_PAGE} from "../consts/pagination"; 4 | 5 | export function getPageOfLogIdsBySingleLogId(briefs, singleLogId) { 6 | const indexOfBrief = findIndex(briefs, item => item.id === singleLogId); 7 | const pageSize = NUMBER_OF_LOG_IN_SINGLE_PAGE; 8 | const pageNum = Math.ceil(briefs.length / pageSize); 9 | const indexOfPage = Math.floor(indexOfBrief / pageSize); 10 | 11 | 12 | if (pageNum <= 3) { 13 | // if the number of pages is less than 3, fetch all 14 | return briefs.map(item => item.id); 15 | } 16 | 17 | if (indexOfPage === 0) { 18 | // if singleLogId is in the first page, fetch the very beginning 3 pages 19 | return briefs.slice(0, 3 * pageSize).map(item => item.id) 20 | } else if (indexOfPage === pageNum - 1) { 21 | // if singleLogId is in the last page, fetch the very last 3 pages 22 | return briefs.slice((pageNum - 3) * pageSize, pageNum * pageSize).map(item => item.id) 23 | } else { 24 | return briefs.slice((indexOfPage - 1) * pageSize, (indexOfPage + 2) * pageSize).map(item => item.id); 25 | } 26 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/consts/logtypes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | export const nativeLogTypeConfigs = [ 4 | { 5 | logType: 1, 6 | logTypeName: "exception catch 日志", 7 | displayColor: "#32CD32" 8 | }, 9 | { 10 | logType: 2, 11 | logTypeName: "custom 代码日志", 12 | displayColor: "#2f54eb" 13 | }, 14 | { 15 | logType: 3, 16 | logTypeName: "network日志", 17 | displayColor: "#5c3317" 18 | }, 19 | { 20 | logType: 84, 21 | logTypeName: "性能日志", 22 | displayColor: "#5c3317" 23 | } 24 | ]; 25 | 26 | export const webLogTypeConfigs = [ 27 | { 28 | logType: 1, 29 | logTypeName: "日志类型1", 30 | displayColor: "#32CD32" 31 | }, 32 | { 33 | logType: 2, 34 | logTypeName: "日志类型2", 35 | displayColor: "#2f54eb" 36 | }, 37 | { 38 | logType: 3, 39 | logTypeName: "日志类型3", 40 | displayColor: "#5c3317" 41 | } 42 | ]; 43 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/consts/minimap-const.test.js: -------------------------------------------------------------------------------- 1 | import * as MinimapConst from "./minimap"; 2 | 3 | describe("Minimap Constants", () => { 4 | it("should match constants value", () => { 5 | const BLUE = "#1890ff"; 6 | const GREY = "#8c8c8c"; 7 | const BAR_TOP_MARGIN = 20; 8 | const BAR_BOTTOM_MARGIN = 20; 9 | const BAR_CSS_WIDTH = 30; 10 | const TIMETEXT_CSS_WIDTH = 8; 11 | const TIMETEXT_STYLE = "22px serif"; 12 | 13 | expect(MinimapConst.BLUE).toBe(BLUE); 14 | expect(MinimapConst.GREY).toBe(GREY); 15 | expect(MinimapConst.BAR_BOTTOM_MARGIN).toBe(BAR_BOTTOM_MARGIN); 16 | expect(MinimapConst.BAR_CSS_WIDTH).toBe(BAR_CSS_WIDTH); 17 | expect(MinimapConst.BAR_TOP_MARGIN).toBe(BAR_TOP_MARGIN); 18 | expect(MinimapConst.TIMETEXT_CSS_WIDTH).toBe(TIMETEXT_CSS_WIDTH); 19 | expect(MinimapConst.TIMETEXT_STYLE).toBe(TIMETEXT_STYLE); 20 | }) 21 | }); -------------------------------------------------------------------------------- /Logan/LoganSite/src/consts/minimap.js: -------------------------------------------------------------------------------- 1 | export const BLUE = "#1890ff"; 2 | export const GREY = "#8c8c8c"; 3 | 4 | export const BAR_TOP_MARGIN = 20; 5 | export const BAR_BOTTOM_MARGIN = 20; 6 | export const BAR_CSS_WIDTH = 30; 7 | export const TIMETEXT_CSS_WIDTH = 8; 8 | 9 | export const TIMETEXT_STYLE = "22px serif"; 10 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/consts/pagination.js: -------------------------------------------------------------------------------- 1 | export const NUMBER_OF_LOG_IN_SINGLE_PAGE = 25; -------------------------------------------------------------------------------- /Logan/LoganSite/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import { Provider } from "react-redux"; 4 | import App from "./app"; 5 | import store from "./store"; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById("root") 12 | ); -------------------------------------------------------------------------------- /Logan/LoganSite/src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, combineReducers } from "redux"; 2 | import { composeWithDevTools } from "redux-devtools-extension"; 3 | import { connectRouter, routerMiddleware } from 'connected-react-router'; 4 | import { createHashHistory } from "history" 5 | import thunk from "redux-thunk"; 6 | 7 | import nativeListReducer from "./views/native-list/redux/reducer"; 8 | import nativeLogDetailReducer from "./views/native-log-detail/redux/reducer"; 9 | import webListReducer from "./views/web-list/redux/reducer"; 10 | import webLogDetailReducer from "./views/web-detail/redux/reducer"; 11 | 12 | const composeEnhancers = composeWithDevTools({}); 13 | 14 | export const history = createHashHistory(); 15 | 16 | const createRootReducer = (history) => combineReducers({ 17 | router: connectRouter(history), 18 | nativeList: nativeListReducer, 19 | nativeLogDetail: nativeLogDetailReducer, 20 | webList: webListReducer, 21 | webLogDetail: webLogDetailReducer 22 | }); 23 | 24 | let store = createStore( 25 | createRootReducer(history), 26 | composeEnhancers( 27 | applyMiddleware( 28 | routerMiddleware(history), 29 | thunk 30 | ) 31 | ) 32 | ); 33 | 34 | export default store; -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/list-page/components/header-bar/style.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | display: flex; 3 | min-width: 1000px; 4 | background: #fff; 5 | padding: 0 16px; 6 | justify-content: space-between; 7 | align-items: center; 8 | position: relative; 9 | } 10 | 11 | .tasklist-filterbar-container { 12 | display: flex; 13 | flex: 1; 14 | margin: 0 16px; 15 | } 16 | 17 | .filterbar-group { 18 | display: flex !important; 19 | flex: 1; 20 | } 21 | 22 | .filter-input { 23 | flex: 1; 24 | min-width: 350px; 25 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/list-page/style.scss: -------------------------------------------------------------------------------- 1 | .listpage-container { 2 | display: flex; 3 | flex: 1; 4 | flex-direction: column; 5 | height: 100%; 6 | 7 | .table-container { 8 | flex: 1; 9 | padding: 32px; 10 | background-color: white; 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/components/filter-bar/style.scss: -------------------------------------------------------------------------------- 1 | .filterbar-container { 2 | background-color: #f0f5ff; 3 | padding: 12px 10px; 4 | margin-bottom: 15px; 5 | border-radius: 5px; 6 | display: flex; 7 | align-items: center; 8 | justify-content: space-between; 9 | min-height: 40px; 10 | } 11 | 12 | .filter-log-type { 13 | margin-right: 20px; 14 | } 15 | 16 | [ant-click-animating-without-extra-node]::after { 17 | opacity: 0; 18 | } 19 | 20 | .log-type-checkbox { 21 | padding: 10px 15px; 22 | width: 250px; 23 | } 24 | 25 | .log-type-checkitem { 26 | margin: 5px 0; 27 | } 28 | 29 | .check-item-wrapper { 30 | display: flex; 31 | align-items: center; 32 | justify-content: space-between; 33 | } 34 | 35 | .sort-type, 36 | .reverse-type, 37 | .tag-check { 38 | padding: 5px 15px; 39 | } 40 | 41 | .sort-type-item, 42 | .reverse-type-item, 43 | .tag-item { 44 | display: block; 45 | line-height: 30px; 46 | } 47 | 48 | .reverse-arrow { 49 | margin-left: 5px; 50 | } 51 | 52 | .filter-keyword-search-wrapper { 53 | padding: 5px; 54 | background-color: #f9f0ff; 55 | border-radius: 5px; 56 | display: flex; 57 | flex: 1; 58 | 59 | .filter-keyword-search { 60 | border: 1px solid #d9d9d9; 61 | border-radius: 0; 62 | border-bottom-right-radius: 5px; 63 | border-top-right-radius: 5px; 64 | 65 | input { 66 | border-radius: 0; 67 | border-bottom-right-radius: 5px; 68 | border-top-right-radius: 5px; 69 | border: none; 70 | height: 100%; 71 | } 72 | 73 | input:hover { 74 | border: none; 75 | } 76 | 77 | input:focus { 78 | outline: 0; 79 | border: none; 80 | box-shadow: none; 81 | -webkit-box-shadow: none; 82 | } 83 | 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/components/log-detail-card/style.scss: -------------------------------------------------------------------------------- 1 | .detail-information-container { 2 | border: solid 1px #e8e8e8; 3 | border-radius: 4px; 4 | min-height: 400px; 5 | max-height: 1700px; 6 | 7 | height: 100%; 8 | margin-left: 10px; 9 | 10 | display: flex; 11 | flex-direction: column; 12 | flex: 0.5; 13 | 14 | header { 15 | display: flex; 16 | justify-content: space-between; 17 | font-weight: 600; 18 | h1 { 19 | line-height: 1rem; 20 | font-size: 1rem; 21 | margin: 0; 22 | } 23 | } 24 | 25 | .ant-card-body { 26 | overflow-y: scroll; 27 | 28 | 29 | 30 | .metadata { 31 | padding-bottom: 12px; 32 | border-bottom: solid 1px #e8e8e8; 33 | } 34 | 35 | .log-content { 36 | padding-top: 12px; 37 | word-break: break-all; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/components/log-information/style.scss: -------------------------------------------------------------------------------- 1 | .log-report-detail { 2 | position: relative; 3 | height: 48px; 4 | margin: 0 20px; 5 | flex: 1; 6 | background: #f7f7f7; 7 | border: 0; 8 | min-width: 300px; 9 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/components/loglist-infinite-scroll/consts.js: -------------------------------------------------------------------------------- 1 | export const LOG_MOVE_DISTANCE = 56; 2 | export const LAST_LOAD_MIN_SPAN = 1500; 3 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/components/time-minimap/style.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/LoganSite/src/views/components/log-detail-page/components/time-minimap/style.module.scss -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/components/log-detail-page/style.scss: -------------------------------------------------------------------------------- 1 | .logdetail-container { 2 | display: flex; 3 | flex-direction: column; 4 | flex: 1; 5 | height: 100%; 6 | 7 | .header { 8 | display: flex; 9 | flex: 1; 10 | align-items: center; 11 | max-height: 64px; 12 | min-height: 64px; 13 | padding: 0 16px; 14 | background-color: #ffffff; 15 | } 16 | 17 | .content { 18 | display: flex; 19 | flex-direction: column; 20 | flex: 1; 21 | min-height: 280px; 22 | min-width: 800px; 23 | margin: 24px 16px; 24 | padding: 24px; 25 | background-color: #ffffff; 26 | 27 | .detail-container { 28 | display: flex; 29 | flex: 1; 30 | height: 100%; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/native-list/redux/action.js: -------------------------------------------------------------------------------- 1 | import { 2 | NATIVE_UPDATE_FILTER_CONDITIONS, 3 | NATIVE_UPDATE_TASKS, 4 | NATIVE_CHANGE_LOADING 5 | } from "./reducer"; 6 | import {fetchNativeTaskApi, fetchNativeListInitData} from "../../../common/api"; 7 | 8 | export function fetchInitData() { 9 | return (dispatch) => { 10 | return fetchNativeListInitData() 11 | .then(data => { 12 | dispatch({ 13 | type: NATIVE_UPDATE_TASKS, 14 | tasks: data 15 | }) 16 | }) 17 | } 18 | } 19 | 20 | export function updateFilterConditions(newFilterConditions) { 21 | return (dispatch, getState) => { 22 | dispatch({ 23 | type: NATIVE_UPDATE_FILTER_CONDITIONS, 24 | filterConditions: newFilterConditions 25 | }); 26 | }; 27 | } 28 | 29 | export function changeLoading(loading) { 30 | return (dispatch, getState) => { 31 | dispatch({ 32 | type: NATIVE_CHANGE_LOADING, 33 | loading: loading 34 | }); 35 | }; 36 | } 37 | 38 | export function fetchTasks({deviceId, platform, beginTime, endTime}) { 39 | return (dispatch, getState) => { 40 | return fetchNativeTaskApi(deviceId, platform, beginTime, endTime) 41 | .then(data => { 42 | dispatch({ 43 | type: NATIVE_UPDATE_TASKS, 44 | tasks: data 45 | }); 46 | }) 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/native-list/redux/initial-state.js: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | export const initialState = { 4 | filterConditions: { 5 | deviceId: "", 6 | platform: 0, 7 | beginTime: moment().startOf("day").subtract(7, 'days'), 8 | endTime: moment().startOf("day") 9 | }, 10 | tasks: [], 11 | loading: false 12 | }; -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/native-list/redux/reducer.js: -------------------------------------------------------------------------------- 1 | import {initialState} from "./initial-state"; 2 | 3 | 4 | export const NATIVE_UPDATE_TASKS = "NATIVE_UPDATE_TASKS"; 5 | export const NATIVE_UPDATE_FILTER_CONDITIONS = "NATIVE_UPDATE_FILTER_CONDITIONS"; 6 | export const NATIVE_CHANGE_LOADING = "NATIVE_CHANGE_LOADING"; 7 | 8 | export default (state = initialState, action) => { 9 | switch (action.type) { 10 | case NATIVE_UPDATE_TASKS: 11 | return { 12 | ...state, 13 | tasks: action.tasks 14 | }; 15 | case NATIVE_UPDATE_FILTER_CONDITIONS: 16 | return { 17 | ...state, 18 | filterConditions: action.filterConditions 19 | }; 20 | case NATIVE_CHANGE_LOADING: 21 | return { 22 | ...state, 23 | loading: action.loading 24 | }; 25 | default: 26 | return state; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/native-log-detail/redux/initial-state.js: -------------------------------------------------------------------------------- 1 | export const initialState = { 2 | // meta data of task 3 | logInfo: null, 4 | 5 | // url of log to download 6 | logDownloadUrl: "", 7 | 8 | // all valid log types 9 | logTypes: [], 10 | 11 | // log types in current task 12 | logTypesInTask: [], 13 | 14 | // briefs of current task 15 | briefs: [], 16 | 17 | // details in this page of current task 18 | taskDetails: [], 19 | 20 | // single log detail (related to focus log) 21 | logDetail: null, 22 | 23 | // focused log id 24 | focusLogId: -1, 25 | 26 | // start index of taskDetails in infinite scroll view 27 | highlightStartIndex: -1, 28 | 29 | // end index of taskDetails in infinite scroll view 30 | highlightEndIndex: -1, 31 | 32 | filterConditions: { 33 | keyword: "", 34 | logTypes: [], 35 | }, 36 | 37 | // whether the log should sorted, true stands for ascending order 38 | sorted: true 39 | }; -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/web-detail/redux/initial-state.js: -------------------------------------------------------------------------------- 1 | export const initialState = { 2 | logInfo: null, 3 | logTypesInTask: [], 4 | briefs: [], 5 | taskDetails: [], 6 | logDetail: null, 7 | 8 | highlightStartIndex: -1, 9 | highlightEndIndex: -1, 10 | focusLogId: -1, 11 | 12 | filterConditions: { 13 | keyword: "", 14 | logTypes: [], 15 | }, 16 | sorted: true 17 | 18 | }; -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/web-list/redux/action.js: -------------------------------------------------------------------------------- 1 | import { 2 | WEB_UPDATE_FILTER_CONDITIONS, 3 | WEB_UPDATE_TASKS, 4 | WEB_CHANGE_LOADING 5 | } from "./reducer"; 6 | import {fetchWebTaskApi, fetchWebListInitData} from "../../../common/api"; 7 | 8 | 9 | export function fetchInitData() { 10 | return (dispatch) => { 11 | return fetchWebListInitData() 12 | .then(data => { 13 | dispatch({ 14 | type: WEB_UPDATE_TASKS, 15 | tasks: data 16 | }) 17 | }) 18 | } 19 | } 20 | 21 | export function updateFilterConditions(newFilterConditions) { 22 | return (dispatch) => { 23 | dispatch({ 24 | type: WEB_UPDATE_FILTER_CONDITIONS, 25 | filterConditions: newFilterConditions 26 | }); 27 | }; 28 | } 29 | 30 | export function changeLoading(loading) { 31 | return (dispatch) => { 32 | dispatch({ 33 | type: WEB_CHANGE_LOADING, 34 | loading: loading 35 | }); 36 | }; 37 | } 38 | 39 | export function fetchTasks({deviceId, beginTime, endTime}) { 40 | return (dispatch) => { 41 | return fetchWebTaskApi(deviceId, beginTime, endTime) 42 | .then(data => { 43 | dispatch({ 44 | type: WEB_UPDATE_TASKS, 45 | tasks: data 46 | }); 47 | }); 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/web-list/redux/initial-state.js: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | export const initialState = { 4 | filterConditions: { 5 | deviceId: "", 6 | beginTime: moment().startOf("day"), 7 | endTime: moment().startOf("day") 8 | }, 9 | tasks: [], 10 | loading: false 11 | }; -------------------------------------------------------------------------------- /Logan/LoganSite/src/views/web-list/redux/reducer.js: -------------------------------------------------------------------------------- 1 | import {initialState as initState} from "./initial-state"; 2 | 3 | 4 | export const WEB_UPDATE_TASKS = "WEB_UPDATE_TASKS"; 5 | export const WEB_UPDATE_FILTER_CONDITIONS = "WEB_UPDATE_FILTER_CONDITIONS"; 6 | export const WEB_CHANGE_LOADING = "WEB_CHANGE_LOADING"; 7 | 8 | export default (state = initState, action) => { 9 | switch (action.type) { 10 | case WEB_UPDATE_TASKS: 11 | return { 12 | ...state, 13 | tasks: action.tasks 14 | }; 15 | case WEB_UPDATE_FILTER_CONDITIONS: 16 | return { 17 | ...state, 18 | filterConditions: action.filterConditions 19 | }; 20 | case WEB_CHANGE_LOADING: 21 | return { 22 | ...state, 23 | loading: action.loading 24 | }; 25 | default: 26 | return state; 27 | } 28 | }; -------------------------------------------------------------------------------- /Logan/README: -------------------------------------------------------------------------------- 1 | # loggan 2 | 3 | ## 使用docker-compose部署 4 | 5 | 部署前将LoganSite下的.env.development.example拷贝一份为.env.development 6 | 该文件为配置前端服务依赖的后端服务地址 7 | 8 | 部署使用命令 9 | 10 | ```sh 11 | docker-compose up -d 12 | ``` 13 | 14 | ### 后端服务 15 | 16 | 本地访问地址: 17 | 18 | ### 前端服务 19 | 20 | 本地访问地址: 21 | 22 | ### phpMyAdmin 23 | 24 | 本地访问,,有一定延迟,无法连接数据库,稍等后重试 25 | 26 | ## 参考 27 | 28 | - maven构建应用镜像 29 | - awesome-compose,样例配置 30 | - csdn 31 | -------------------------------------------------------------------------------- /Logan/Server/Dockerfile: -------------------------------------------------------------------------------- 1 | # 参考: https://developer.aliyun.com/article/65274 2 | FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8 AS build-env 3 | 4 | ENV MY_HOME=/app 5 | RUN mkdir -p $MY_HOME 6 | WORKDIR $MY_HOME 7 | ADD pom.xml $MY_HOME 8 | 9 | # get all the downloads out of the way 10 | RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","verify","clean","--fail-never"] 11 | 12 | # add source 13 | ADD . $MY_HOME 14 | 15 | # run maven verify 16 | RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","verify"] 17 | 18 | # Second stage - build image 19 | FROM tomcat:7.0.61-jre8 20 | 21 | COPY --from=build-env /app/target/*.war /usr/local/tomcat/webapps/logan-web.war 22 | 23 | ENV JAVA_OPTS="" 24 | ENV SERVER_PORT 8080 25 | 26 | EXPOSE ${SERVER_PORT} -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/controller/WebLogUploadController.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.controller; 2 | 3 | import com.meituan.logan.web.model.WebLogTaskModel; 4 | import com.meituan.logan.web.model.response.LoganResponse; 5 | import com.meituan.logan.web.parser.WebLogParser; 6 | import com.meituan.logan.web.service.WebTaskService; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | 12 | /** 13 | * 功能描述:

负责接受H5端上报的日志

14 | * 15 | * @version 1.0 2019-10-31 16 | * @since logan-web 1.0 17 | */ 18 | @CrossOrigin(origins = "*", maxAge = 3600) 19 | @Controller 20 | @RequestMapping("/logan/web") 21 | public class WebLogUploadController { 22 | 23 | @Resource 24 | private WebTaskService webTaskService; 25 | 26 | /** 27 | * 接收并存储H5端上报的日志 28 | * 29 | * @param taskModel H5上报 30 | * @return LoganResponse 31 | */ 32 | @PostMapping("/upload.json") 33 | @ResponseBody 34 | public LoganResponse receiveWebLog(@RequestBody WebLogTaskModel taskModel) { 35 | if (taskModel == null || !taskModel.isValid()) { 36 | return LoganResponse.badParam("invalid params"); 37 | } 38 | taskModel.setContent(WebLogParser.parse(taskModel.getLogArray())); 39 | if (webTaskService.saveTask(taskModel)) { 40 | return LoganResponse.success(true); 41 | } 42 | return LoganResponse.exception("save log error"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/dto/LoganLogDetailDTO.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.dto; 2 | 3 | import com.meituan.logan.web.model.LoganLogDetailModel; 4 | import com.meituan.logan.web.model.LoganLogSimpleModel; 5 | import lombok.Data; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @since 2019-10-14 15:22 11 | * @since logan-web 1.0 12 | */ 13 | @Data 14 | public class LoganLogDetailDTO implements Comparable { 15 | 16 | private long id; 17 | 18 | private long taskId; 19 | 20 | private int logType; 21 | 22 | private String content; 23 | 24 | private long logTime; 25 | 26 | private Date addTime; 27 | 28 | private Date updateTime; 29 | 30 | @Override 31 | public int compareTo(LoganLogDetailDTO o) { 32 | if (null == o) { 33 | return 0; 34 | } 35 | return id - o.getId() > 0 ? 1 : -1; 36 | } 37 | 38 | public LoganLogDetailModel transformToModel() { 39 | LoganLogDetailModel model = new LoganLogDetailModel(); 40 | model.setId(id); 41 | model.setTaskId(taskId); 42 | model.setLogType(logType); 43 | model.setContent(content); 44 | model.setLogTime(logTime); 45 | return model; 46 | } 47 | 48 | public LoganLogSimpleModel transformToSimple() { 49 | LoganLogSimpleModel model = new LoganLogSimpleModel(); 50 | model.setId(id); 51 | model.setLogType(logType); 52 | model.setLogTime(logTime); 53 | return model; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/dto/LoganTaskDTO.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.dto; 2 | 3 | import com.meituan.logan.web.model.LoganTaskModel; 4 | import lombok.Data; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @since 2019-10-14 15:22 10 | * @since logan-web 1.0 11 | */ 12 | @Data 13 | public class LoganTaskDTO implements Comparable { 14 | 15 | private long id; 16 | 17 | private String amount; 18 | 19 | private String appId; 20 | 21 | private String unionId; 22 | 23 | private int platform; 24 | 25 | private String buildVersion; 26 | 27 | private String appVersion; 28 | 29 | private String deviceId; 30 | 31 | private long logDate; 32 | 33 | private String logFileName; 34 | 35 | private long addTime; 36 | 37 | private int status; 38 | 39 | private Date updateTime; 40 | 41 | @Override 42 | public int compareTo(LoganTaskDTO o) { 43 | if (null == o) { 44 | return 0; 45 | } 46 | if (logDate == o.logDate) { 47 | return id < o.getId() ? 1 : -1; 48 | } 49 | return logDate < o.getLogDate() ? 1 : -1; 50 | } 51 | 52 | public LoganTaskModel transformToModel() { 53 | LoganTaskModel result = new LoganTaskModel(); 54 | result.setTaskId(id); 55 | result.setAmount(amount); 56 | result.setAppId(appId); 57 | result.setUnionId(unionId); 58 | result.setBuildVersion(buildVersion); 59 | result.setAppVersion(appVersion); 60 | result.setDeviceId(deviceId); 61 | result.setPlatform(platform); 62 | result.setLogDate(logDate); 63 | result.setLogFileName(logFileName); 64 | result.setAddTime(addTime); 65 | result.setStatus(status); 66 | return result; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/dto/WebLogDetailDTO.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.dto; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * @version 1.0 2019-10-31 9 | * @since logan-web 1.0 10 | */ 11 | @Data 12 | public class WebLogDetailDTO implements Comparable { 13 | private long id; 14 | 15 | private long taskId; 16 | 17 | private int logType; 18 | 19 | private String content; 20 | 21 | private long logTime; 22 | 23 | private int logLevel; 24 | 25 | private int minuteOffset; 26 | 27 | private long addTime = System.currentTimeMillis(); 28 | 29 | @Override 30 | public int compareTo(WebLogDetailDTO o) { 31 | if (null == o) { 32 | return 0; 33 | } 34 | return (int) (this.logTime - o.getLogTime()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/dto/WebLogTaskDTO.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.Data; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * 功能描述:

10 | * 11 | * @version 1.0 2019-10-30 12 | * @since logan-web 1.0 13 | */ 14 | @Data 15 | public class WebLogTaskDTO implements Comparable { 16 | private long taskId; 17 | 18 | /** 19 | * 设备标示 20 | */ 21 | private String deviceId; 22 | 23 | /** 24 | * 来源 25 | */ 26 | private String webSource; 27 | 28 | /** 29 | * 环境信息 30 | */ 31 | private String environment; 32 | 33 | private int pageNum; 34 | 35 | @JsonIgnore 36 | private String content; 37 | 38 | /** 39 | * 日志上报时间 40 | */ 41 | private long addTime = System.currentTimeMillis(); 42 | 43 | /** 44 | * 日志所属天 45 | */ 46 | private long logDate; 47 | 48 | /** 49 | * 0:未解析过,1:解析过 50 | */ 51 | private int status = 0; 52 | 53 | /** 54 | * 客户端上报元信息 55 | */ 56 | private String customReportInfo; 57 | 58 | /** 59 | * 汇集多个taskId为一个task组 60 | */ 61 | private String tasks; 62 | 63 | private Date updateTime; 64 | 65 | @Override 66 | public int compareTo(WebLogTaskDTO o) { 67 | if (null == o) { 68 | return 0; 69 | } 70 | return this.pageNum - o.getPageNum(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/enums/LogTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.enums; 2 | 3 | import com.meituan.logan.web.model.Tuple; 4 | import lombok.Getter; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | 9 | /** 10 | * 功能描述:

客户端日志类型,各使用方可自行定义

11 | * 12 | * @version 1.0 2019-10-07 13 | * @since logan-web 1.0 14 | */ 15 | public enum LogTypeEnum { 16 | UNKNOWN(0, "unknown"), ONE(1, "日志类型1"), TWO(2, "日志类型2"), THREE(3, "日志类型3"); 17 | 18 | @Getter 19 | private int logType; 20 | 21 | @Getter 22 | private String logDesc; 23 | 24 | LogTypeEnum(int logType, String logDesc) { 25 | this.logDesc = logDesc; 26 | this.logType = logType; 27 | } 28 | 29 | public static LogTypeEnum valueOfLogType(int logType) { 30 | for (LogTypeEnum en : LogTypeEnum.values()) { 31 | if (en.getLogType() == logType) { 32 | return en; 33 | } 34 | } 35 | return UNKNOWN; 36 | } 37 | 38 | public static List> allLogTypes() { 39 | List> logTypes = new LinkedList<>(); 40 | for (LogTypeEnum logType : LogTypeEnum.values()) { 41 | if (logType != UNKNOWN) { 42 | logTypes.add(Tuple.create(logType.logType, logType.logDesc)); 43 | } 44 | } 45 | return logTypes; 46 | } 47 | 48 | public static boolean contains(int logType) { 49 | for (LogTypeEnum en : LogTypeEnum.values()) { 50 | if (en.logType == logType) { 51 | return true; 52 | } 53 | } 54 | return false; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/enums/PlatformEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * 功能描述:

客户端平台枚举类

7 | * 8 | * @version 1.0 2019-10-07 9 | * @since logan-web 1.0 10 | */ 11 | public enum PlatformEnum { 12 | UNKNOWN(-1, "unknown"), ALL(0, "all"), ANDROID(1, "android"), IOS(2, "iOS"); 13 | 14 | @Getter 15 | private int platform; 16 | 17 | @Getter 18 | private String desc; 19 | 20 | PlatformEnum(int platform, String desc) { 21 | this.desc = desc; 22 | this.platform = platform; 23 | } 24 | 25 | public static PlatformEnum valueOfPlatform(Integer platform) { 26 | for (PlatformEnum platformEnum : PlatformEnum.values()) { 27 | if (platformEnum.platform == platform) { 28 | return platformEnum; 29 | } 30 | } 31 | return UNKNOWN; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/enums/ResultEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.enums; 2 | 3 | public enum ResultEnum { 4 | SUCCESS,//成功 5 | ERROR_PARAM,//参数错误 6 | EXCEPTION,//日志解析异常 7 | ERROR_LOG_PATH,//文件路径创建失败 8 | ERROR_DECRYPT,//解密过程中出错 9 | ERROR_DATABASE;//保存到数据库出错 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/enums/TaskStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * 功能描述:

日志任务状态

7 | * 8 | * @version 1.0 2019-10-07 9 | * @since logan-web 1.0 10 | */ 11 | public enum TaskStatusEnum { 12 | 13 | NORMAL(0, "未经分析"), ANALYZED(1, "已经被分析过"); 14 | 15 | @Getter 16 | private int status; 17 | 18 | @Getter 19 | private String desc; 20 | 21 | TaskStatusEnum(int status, String desc) { 22 | this.desc = desc; 23 | this.status = status; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/enums/WebLogFieldEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.enums; 2 | 3 | /** 4 | * 功能描述:

H5端日志字段枚举

5 | * 6 | * @version 1.0 2019-11-01 7 | * @since logan-web 1.0 8 | */ 9 | public enum WebLogFieldEnum { 10 | 11 | VERSION("v", "加密版本"), LOG("l", "日志体"), IV("iv", "客户端IV"), KEY("k", "客户端非对称加密AES key"), LOG_TYPE( 12 | "t", "日志类型"), CONTENT("c", "日志内容"), LOG_TIME("d", "客户端记录日志的时间"); 13 | 14 | public String key; 15 | public String desc; 16 | 17 | WebLogFieldEnum(String key, String desc) { 18 | this.desc = desc; 19 | this.key = key; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/handler/ContentHandler.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.handler; 2 | 3 | /** 4 | * 日志格式化接口,使用可自行实现各种日志类型的格式化操作 5 | */ 6 | public interface ContentHandler { 7 | 8 | String getSimpleContent(String content); 9 | 10 | String getFormatContent(String content); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/handler/LoganTypeOneHandler.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.handler; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * 7 | * @since 2019-10-29 20:22 8 | */ 9 | @Component 10 | public class LoganTypeOneHandler implements ContentHandler { 11 | @Override 12 | public String getSimpleContent(String content) { 13 | return content; 14 | } 15 | 16 | @Override 17 | public String getFormatContent(String content) { 18 | return content; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/handler/LoganTypeThreeHandler.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.handler; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * @since 2019-10-29 20:22 7 | */ 8 | @Component 9 | public class LoganTypeThreeHandler implements ContentHandler { 10 | @Override 11 | public String getSimpleContent(String content) { 12 | return content; 13 | } 14 | 15 | @Override 16 | public String getFormatContent(String content) { 17 | return content; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/handler/LoganTypeTwoHandler.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.handler; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * @since 2019-10-29 20:22 7 | */ 8 | @Component 9 | public class LoganTypeTwoHandler implements ContentHandler { 10 | @Override 11 | public String getSimpleContent(String content) { 12 | return content; 13 | } 14 | 15 | @Override 16 | public String getFormatContent(String content) { 17 | return content; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/handler/LoganTypeUnknownHandler.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.handler; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * @since 2019-10-29 20:02 7 | */ 8 | @Component 9 | public class LoganTypeUnknownHandler implements ContentHandler { 10 | 11 | @Override 12 | public String getSimpleContent(String content) { 13 | return content; 14 | } 15 | 16 | @Override 17 | public String getFormatContent(String content) { 18 | return content; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/mapper/LoganLogDetailMapper.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.mapper; 2 | 3 | import com.meituan.logan.web.dto.LoganLogDetailDTO; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | import java.util.List; 7 | 8 | public interface LoganLogDetailMapper { 9 | 10 | void insert(@Param("dto") LoganLogDetailDTO dto); 11 | 12 | void batchInsert(@Param("list") List list); 13 | 14 | LoganLogDetailDTO selectById(@Param("id") long id); 15 | 16 | List queryByTaskIdTypeKeyword(@Param("taskId") long taskId, 17 | @Param("types") List types, @Param("keyword") String keyword); 18 | 19 | List queryByIds(@Param("ids") List detailIds); 20 | } 21 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/mapper/LoganTaskMapper.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.mapper; 2 | 3 | import com.meituan.logan.web.dto.LoganTaskDTO; 4 | import com.meituan.logan.web.model.request.LoganTaskRequest; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface LoganTaskMapper { 10 | 11 | void insert(@Param("dto") LoganTaskDTO dto); 12 | 13 | void updateStatus(@Param("id") long id, @Param("status") int status); 14 | 15 | LoganTaskDTO selectById(@Param("id") long id); 16 | 17 | List search(@Param("request") LoganTaskRequest request); 18 | 19 | List queryLatest(@Param("limit") int limit); 20 | } 21 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/mapper/WebLogDetailMapper.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.mapper; 2 | 3 | import com.meituan.logan.web.dto.WebLogDetailDTO; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | import java.util.List; 7 | 8 | public interface WebLogDetailMapper { 9 | void batchInsert(@Param("details") List webLogDetailDTO); 10 | 11 | WebLogDetailDTO queryById(@Param("id") long id); 12 | 13 | void deleteByRange(@Param("lowerBound") long lowerBound, @Param("upperBound") long upperBound); 14 | 15 | List queryByIds(@Param("ids") List ids); 16 | 17 | List match(@Param("taskId") long taskId, 18 | @Param("beginTimeOffset") int beginTimeOffset, 19 | @Param("endTimeOffset") int endTimeOffset, @Param("logTypes") List logTypes); 20 | } 21 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/mapper/WebLogTaskMapper.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.mapper; 2 | 3 | import com.meituan.logan.web.dto.WebLogTaskDTO; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | import java.util.List; 7 | 8 | public interface WebLogTaskMapper { 9 | 10 | void insert(@Param("task") WebLogTaskDTO taskDTO); 11 | 12 | void updateContent(@Param("taskId") long taskId, @Param("content") String content); 13 | 14 | WebLogTaskDTO exist(@Param("logDate") long logDate, @Param("deviceId") String deviceId, 15 | @Param("pageNum") int pageNum); 16 | 17 | List query(@Param("beginTime") long beginTime, @Param("endTime") long endTime, 18 | @Param("deviceId") String deviceId); 19 | 20 | void deleteByAddTime(@Param("addTime") long addTime); 21 | 22 | List queryByIds(@Param("tasks") List taskIds); 23 | 24 | void updateStatus(@Param("taskId") long taskId, @Param("status") int status); 25 | 26 | long maxId(); 27 | 28 | List queryByRange(@Param("minId") long minId, @Param("maxId")long maxId); 29 | } 30 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/LoganLogDetailModel.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * 9 | * @version 1.0 2019-10-07 10 | * @since logan-web 1.0 11 | */ 12 | @Data 13 | public class LoganLogDetailModel { 14 | private long id; 15 | 16 | private long taskId; 17 | 18 | private int logType; 19 | 20 | /** 21 | * 原始日志 22 | */ 23 | private String content; 24 | 25 | /** 26 | * 日志摘要 27 | */ 28 | private String simpleContent; 29 | /** 30 | * 日志详情 31 | */ 32 | private String formatContent; 33 | 34 | private long logTime; 35 | } 36 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/LoganLogItem.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import com.meituan.logan.web.dto.LoganLogDetailDTO; 4 | import com.meituan.logan.web.enums.LogTypeEnum; 5 | import lombok.Data; 6 | import org.apache.commons.lang3.math.NumberUtils; 7 | 8 | /** 9 | * 10 | * 11 | * 12 | * @since 2019-11-12 17:13 13 | */ 14 | @Data 15 | public class LoganLogItem { 16 | private String c;//content 17 | private String f;//logType 18 | private String l;//logTime 19 | private String n;//theadName 20 | private String i;//threadid 21 | private String m;//是否是主线程 22 | 23 | public LoganLogDetailDTO transferToDetail(long taskId) { 24 | LoganLogDetailDTO dto = new LoganLogDetailDTO(); 25 | dto.setTaskId(taskId); 26 | dto.setLogType(LogTypeEnum.valueOfLogType(NumberUtils.toInt(f)).getLogType()); 27 | dto.setContent(c); 28 | dto.setLogTime(NumberUtils.toLong(l)); 29 | return dto; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/LoganLogSimpleModel.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * 9 | * @version 1.0 2019-10-07 10 | * @since logan-web 1.0 11 | */ 12 | @Data 13 | public class LoganLogSimpleModel implements Comparable { 14 | private long id; 15 | 16 | private int logType; 17 | 18 | private long logTime; 19 | 20 | @Override 21 | public int compareTo(LoganLogSimpleModel o) { 22 | return (int) (this.logTime - o.logTime); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/LoganTaskModel.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import com.meituan.logan.web.dto.LoganTaskDTO; 4 | import com.meituan.logan.web.enums.TaskStatusEnum; 5 | import lombok.Data; 6 | 7 | /** 8 | * 功能描述:

9 | * 10 | * @version 1.0 2019-10-07 11 | * @since logan-web 1.0 12 | */ 13 | @Data 14 | public class LoganTaskModel { 15 | 16 | private long taskId; 17 | 18 | private String amount; 19 | 20 | private String appId; 21 | 22 | private String unionId; 23 | 24 | private int platform; 25 | 26 | private String buildVersion; 27 | 28 | private String appVersion; 29 | 30 | private String deviceId; 31 | /** 32 | * 日志所属天 33 | */ 34 | private long logDate; 35 | /** 36 | * 文件名 37 | */ 38 | private String logFileName; 39 | /** 40 | * 日志上报时间 41 | */ 42 | private long addTime; 43 | /** 44 | * 0 : 未分析过,1 : 已分析过 45 | */ 46 | private int status; 47 | 48 | public LoganTaskDTO transformToDto() { 49 | LoganTaskDTO dto = new LoganTaskDTO(); 50 | dto.setAmount(amount); 51 | dto.setAppId(appId); 52 | dto.setUnionId(unionId); 53 | dto.setBuildVersion(buildVersion); 54 | dto.setPlatform(platform); 55 | dto.setAppVersion(appVersion); 56 | dto.setDeviceId(deviceId); 57 | dto.setLogFileName(logFileName); 58 | dto.setAddTime(addTime); 59 | dto.setLogDate(logDate); 60 | dto.setStatus(TaskStatusEnum.NORMAL.getStatus()); 61 | return dto; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/Tuple.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * 9 | * @version 1.0 2019-10-07 10 | * @since logan-web 1.0 11 | */ 12 | @Data 13 | public class Tuple { 14 | private K first; 15 | 16 | private V second; 17 | 18 | public static Tuple create(K first, V second) { 19 | Tuple tuple = new Tuple<>(); 20 | tuple.first = first; 21 | tuple.second = second; 22 | return tuple; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/WebLogIndex.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 功能描述:

9 | * 10 | * 11 | * @version 1.0 2019-11-08 12 | * @since logan-web 1.0 13 | */ 14 | @Data 15 | public class WebLogIndex implements Serializable { 16 | 17 | private long detailId; 18 | 19 | private int logType; 20 | 21 | private long logTime; 22 | 23 | public WebLogIndex(long detailId, int logType, long logTime){ 24 | this.detailId = detailId; 25 | this.logTime = logTime; 26 | this.logType = logType; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/request/LoganTaskRequest.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model.request; 2 | 3 | import com.meituan.logan.web.enums.PlatformEnum; 4 | import com.meituan.logan.web.util.DateTimeUtil; 5 | import com.meituan.logan.web.util.TypeSafeUtil; 6 | import lombok.Data; 7 | 8 | /** 9 | * 功能描述:

10 | * 11 | * @version 1.0 2019-10-07 12 | * @since logan-web 1.0 13 | */ 14 | @Data 15 | public class LoganTaskRequest { 16 | private String deviceId; 17 | 18 | private Long beginTime; 19 | 20 | private Long endTime; 21 | 22 | private Integer platform; 23 | 24 | /** 25 | * 调整参数 26 | */ 27 | public void ready() { 28 | this.platform = TypeSafeUtil.nullToDefault(this.platform, PlatformEnum.ALL.getPlatform()); 29 | this.endTime = TypeSafeUtil.nullToDefault(this.endTime + DateTimeUtil.ONE_DAY, System.currentTimeMillis()); 30 | this.beginTime = TypeSafeUtil.nullToDefault(this.beginTime, 31 | this.endTime - TypeSafeUtil.SEVEN_DAY); 32 | } 33 | 34 | public LoganTaskRequest(String deviceId, Long beginTime, Long endTime, Integer platform) { 35 | this.deviceId = deviceId; 36 | this.beginTime = beginTime; 37 | this.endTime = endTime; 38 | this.platform = platform; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/model/response/LoganResponse.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.model.response; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * 9 | * @version 1.0 2019-10-07 10 | * @since logan-web 1.0 11 | */ 12 | @Data 13 | public class LoganResponse { 14 | public static final int SUCCESS = 200; 15 | public static final int SERVER_EXCEPTION = 500; 16 | public static final int BAD_PARAM = 400; 17 | 18 | private int code; 19 | private String msg; 20 | private T data; 21 | 22 | public static LoganResponse success(T data) { 23 | LoganResponse response = new LoganResponse<>(); 24 | response.setCode(SUCCESS); 25 | response.setData(data); 26 | return response; 27 | } 28 | 29 | public static LoganResponse exception(String msg) { 30 | return fail(msg, SERVER_EXCEPTION); 31 | } 32 | 33 | public static LoganResponse badParam(String msg) { 34 | return fail(msg, BAD_PARAM); 35 | } 36 | 37 | private static LoganResponse fail(String msg, int errorCode) { 38 | LoganResponse response = new LoganResponse<>(); 39 | response.setCode(errorCode); 40 | response.setMsg(msg); 41 | return response; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/BatchInsertService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * 9 | * @version 1.0 2019-10-31 10 | * @since logan-admin-server 1.0 11 | */ 12 | public interface BatchInsertService { 13 | 14 | void saveLogDetail(T data); 15 | 16 | void saveLogDetails(List list); 17 | } 18 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/HandlerDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.enums.LogTypeEnum; 4 | import com.meituan.logan.web.handler.ContentHandler; 5 | 6 | /** 7 | * @since 2019-10-29 20:31 8 | */ 9 | 10 | public interface HandlerDispatcher { 11 | 12 | ContentHandler getHandler(LogTypeEnum logTypeEnum); 13 | } 14 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/LoganLogDetailService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.model.LoganLogDetailModel; 4 | import com.meituan.logan.web.model.LoganLogSimpleModel; 5 | 6 | import java.util.List; 7 | 8 | public interface LoganLogDetailService { 9 | 10 | List> listByTaskIdTypeKeyword(long taskId, List type, String keyword); 11 | 12 | List listByDetailIds(List detailIds); 13 | 14 | LoganLogDetailModel getByDetailId(long detailId); 15 | } 16 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/LoganLogFileService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.enums.ResultEnum; 4 | 5 | import java.io.InputStream; 6 | 7 | /** 8 | * @since 2019-11-08 16:01 9 | */ 10 | public interface LoganLogFileService { 11 | 12 | ResultEnum write(InputStream inputStream, String fileName); 13 | } 14 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/LoganTaskService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.model.LoganTaskModel; 4 | import com.meituan.logan.web.model.request.LoganTaskRequest; 5 | 6 | import java.util.List; 7 | 8 | public interface LoganTaskService { 9 | 10 | List search(LoganTaskRequest request); 11 | 12 | LoganTaskModel getByTaskId(long taskId); 13 | 14 | long insertTask(LoganTaskModel loganTaskModel); 15 | 16 | List queryLatest(int limit); 17 | } 18 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/WebLogDetailService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.dto.WebLogDetailDTO; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 功能描述:

9 | * 10 | * 11 | * @version 1.0 2019-10-31 12 | * @since logan-admin-server 1.0 13 | */ 14 | public interface WebLogDetailService { 15 | 16 | WebLogDetailDTO queryById(long detailId); 17 | 18 | void deleteByRange(long lowerBound, long upperBound); 19 | 20 | List queryByIds(List detailIds); 21 | 22 | List match(long taskId, int beginTimeOffset, int endTimeOffset, 23 | List logTypes, String keyword); 24 | } 25 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/WebTaskService.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service; 2 | 3 | import com.meituan.logan.web.dto.WebLogTaskDTO; 4 | import com.meituan.logan.web.enums.TaskStatusEnum; 5 | import com.meituan.logan.web.model.WebLogTaskModel; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 功能描述:

11 | * 12 | * 13 | * @version 1.0 2019-10-30 14 | * @since logan-admin-server 1.0 15 | */ 16 | public interface WebTaskService { 17 | 18 | /** 19 | * 新增/更新一次上报 20 | * 21 | * @param webLogTaskModel 22 | */ 23 | boolean saveTask(WebLogTaskModel webLogTaskModel); 24 | 25 | /** 26 | * 删除addTime之前的记录,单位 ms 27 | * 28 | * @param addTime 29 | */ 30 | void deleteByAddTime(long addTime); 31 | 32 | /** 33 | * 根据起始与截止时间进行搜索,3个参数必填,基于deviceId精确匹配 34 | * 35 | * @param beginTime 36 | * @param endTime 37 | * @param deviceId 38 | * @return 39 | */ 40 | List search(long beginTime, long endTime, String deviceId); 41 | 42 | List queryByTaskIds(List taskIds); 43 | 44 | void updateStatus(long taskId, TaskStatusEnum status); 45 | 46 | List latest(int count); 47 | } 48 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/impl/HandlerDispatcherDefaultImpl.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service.impl; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.meituan.logan.web.enums.LogTypeEnum; 5 | import com.meituan.logan.web.handler.*; 6 | import com.meituan.logan.web.service.HandlerDispatcher; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.annotation.PostConstruct; 10 | import javax.annotation.Resource; 11 | import java.util.Map; 12 | 13 | @Component 14 | public class HandlerDispatcherDefaultImpl implements HandlerDispatcher { 15 | 16 | private Map handlers = Maps.newConcurrentMap(); 17 | 18 | @Resource 19 | private LoganTypeOneHandler oneHandler; 20 | @Resource 21 | private LoganTypeTwoHandler twoHandler; 22 | @Resource 23 | private LoganTypeThreeHandler threeHandler; 24 | @Resource 25 | private LoganTypeUnknownHandler unknownHandler; 26 | 27 | @PostConstruct 28 | public void init() { 29 | handlers.put(LogTypeEnum.ONE, oneHandler); 30 | handlers.put(LogTypeEnum.TWO, twoHandler); 31 | handlers.put(LogTypeEnum.THREE, threeHandler); 32 | handlers.put(LogTypeEnum.UNKNOWN, unknownHandler); 33 | } 34 | 35 | @Override 36 | public ContentHandler getHandler(LogTypeEnum logTypeEnum) { 37 | ContentHandler handler = handlers.get(logTypeEnum); 38 | return handler == null ? unknownHandler : handler; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/service/impl/LoganLogFileServiceDefaultImpl.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.service.impl; 2 | 3 | import com.meituan.logan.web.enums.ResultEnum; 4 | import com.meituan.logan.web.parser.LoganProtocol; 5 | import com.meituan.logan.web.service.LoganLogFileService; 6 | import com.meituan.logan.web.util.FileUtil; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.apache.log4j.Logger; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.io.File; 12 | import java.io.InputStream; 13 | 14 | @Service 15 | public class LoganLogFileServiceDefaultImpl implements LoganLogFileService { 16 | 17 | private static final Logger LOGGER = Logger.getLogger(LoganLogFileServiceDefaultImpl.class); 18 | 19 | @Override 20 | public ResultEnum write(InputStream inputStream, String fileName) { 21 | if (inputStream == null|| StringUtils.isEmpty(fileName)) { 22 | return ResultEnum.ERROR_PARAM; 23 | } 24 | try { 25 | File file = FileUtil.createNewFile(fileName); 26 | if (file == null) { 27 | return ResultEnum.ERROR_LOG_PATH; 28 | } 29 | return new LoganProtocol(inputStream, file).process(); 30 | } catch (Exception e) { 31 | LOGGER.error(e); 32 | } 33 | return ResultEnum.EXCEPTION; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/task/DelaySupplier.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.task; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public interface DelaySupplier { 6 | 7 | long getInitialDelay(); 8 | 9 | int getPeriod(); 10 | 11 | TimeUnit getTimeUnit(); 12 | } 13 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.task; 2 | 3 | 4 | public interface Task { 5 | void exec(); 6 | } 7 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/task/TaskLoop.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.task; 2 | 3 | 4 | 5 | public interface TaskLoop { 6 | void submitTask(Task task); 7 | 8 | void registerHarvestTask(Task task); 9 | 10 | void setDelaySupplier(DelaySupplier delaySupplier); 11 | 12 | void start(); 13 | 14 | long getBlockedTask(); 15 | } 16 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/DateFormatStyleEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | /** 4 | * 功能描述:

5 | * 6 | * 7 | * @version 1.0 2019-08-23 8 | * @since logan-web 1.0 9 | */ 10 | public enum DateFormatStyleEnum { 11 | DATE_TIME("yyyy-MM-dd HH:mm:ss"), DATE("yyyy-MM-dd"), TIME("HH:mm:ss"), MONTH_DAY("MM-dd"), YMD( 12 | "yyyyMMdd"); 13 | public String style; 14 | 15 | DateFormatStyleEnum(String style) { 16 | this.style = style; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | /** 10 | * 类描述:文件处理工具类 11 | * * @since 2019-11-25 17:01 12 | */ 13 | public class FileUtil { 14 | 15 | public static File createNewFile(String fileName) { 16 | File file = getFile(fileName); 17 | if (file == null) { 18 | return null; 19 | } 20 | if (!file.getParentFile().exists()) { 21 | file.getParentFile().mkdirs(); 22 | } 23 | if (file.exists()) { 24 | file.delete(); 25 | } 26 | try { 27 | file.createNewFile(); 28 | } catch (IOException e) { 29 | return null; 30 | } 31 | return file; 32 | } 33 | 34 | public static File getFile(String fileName) { 35 | String path = new File("").getAbsolutePath() + File.separator + "logfile" + File.separator; 36 | File file = new File(path + fileName); 37 | if (!path.equals(file.getParentFile().getAbsolutePath()+ File.separator)) { 38 | return null; 39 | } 40 | return file; 41 | } 42 | 43 | public static String getDownloadUrl(HttpServletRequest request, String fileName) { 44 | if (StringUtils.isEmpty(fileName) || request == null) { 45 | return ""; 46 | } 47 | return "/logan/downing?name=" + fileName; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/LocalStringUtils.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | /** 6 | * 功能描述:

7 | * 8 | * @version 1.0 2019-10-31 9 | * @since logan-web 1.0 10 | */ 11 | public class LocalStringUtils { 12 | 13 | public static boolean isAllNotEmpty(String... strings) { 14 | for (String item : strings) { 15 | if (StringUtils.isEmpty(item)) { 16 | return false; 17 | } 18 | } 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/OrderUtil.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | import org.springframework.util.CollectionUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.function.Function; 9 | 10 | /** 11 | * @since 2019-10-18 10:47 12 | */ 13 | public class OrderUtil { 14 | 15 | public static List order(List source, List target, Function func) { 16 | if (CollectionUtils.isEmpty(source) || CollectionUtils.isEmpty(target)) { 17 | return Collections.emptyList(); 18 | } 19 | List temp = new ArrayList<>(Collections.nCopies(target.size(), null)); 20 | for (T t : source) { 21 | int index = target.indexOf(func.apply(t)); 22 | if (index != -1 && temp.get(index) == null) { 23 | temp.set(index, t); 24 | } 25 | } 26 | return temp; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/Threads.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 4 | import org.apache.commons.lang3.concurrent.BasicThreadFactory; 5 | 6 | import java.util.concurrent.*; 7 | 8 | /** 9 | * 功能描述:

10 | * 11 | * @version 1.0 2019-10-31 12 | * @since logan-web 1.0 13 | */ 14 | public class Threads { 15 | private static final String COMMON_PREFIX = "logan-web-"; 16 | private static final String SCHEDULE_PREFIX = "logan-web-schedule-"; 17 | 18 | /** 19 | * 创建单线程 20 | * 21 | * @param name 待创建的线程名称 22 | */ 23 | 24 | public static ExecutorService newSingleThreadExecutor(String name) { 25 | return new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, 26 | new LinkedBlockingQueue<>(5000), getCommonThreadFactory(name), 27 | new ThreadPoolExecutor.AbortPolicy()); 28 | } 29 | 30 | /** 31 | * 创建定时任务单线程 32 | * 33 | * @param name 待创建的线程名称 34 | */ 35 | public static ScheduledExecutorService newSingleThreadScheduledExecutor(String name) { 36 | return new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern( 37 | SCHEDULE_PREFIX + name + "-%d").daemon(true).build()); 38 | } 39 | 40 | public static ExecutorService newFixedThreadPool(String name, int nThread) { 41 | return new ThreadPoolExecutor(nThread, nThread, 0, TimeUnit.MILLISECONDS, 42 | new LinkedBlockingQueue<>(5000), getCommonThreadFactory(name), 43 | new ThreadPoolExecutor.AbortPolicy()); 44 | } 45 | 46 | private static ThreadFactory getCommonThreadFactory(String name) { 47 | return new ThreadFactoryBuilder().setNameFormat(COMMON_PREFIX + name + "-%d").build(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Logan/Server/src/main/java/com/meituan/logan/web/util/TrimFieldEnum.java: -------------------------------------------------------------------------------- 1 | package com.meituan.logan.web.util; 2 | 3 | /** 4 | * 功能描述:

5 | * 6 | * @version 1.0 2019-08-23 7 | * @since logan-web 1.0 8 | */ 9 | public enum TrimFieldEnum { 10 | HOUR, MINUTE, SECOND, MIL_SECOND 11 | } 12 | -------------------------------------------------------------------------------- /Logan/Server/src/main/resources/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driver=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://host:port/database?characterEncoding=UTF8&allowMultiQueries=true&socketTimeout=60000&autoReconnect=true 3 | jdbc.username=username 4 | jdbc.password=password -------------------------------------------------------------------------------- /Logan/Server/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=ERROR,R,stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n 6 | 7 | log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 8 | log4j.appender.R.File=/data/applogs/logan-web/logan.log 9 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 10 | log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n 11 | -------------------------------------------------------------------------------- /Logan/Server/src/main/resources/secure.properties: -------------------------------------------------------------------------------- 1 | AES_KEY=0123456789012345 2 | IV=0123456789012345 -------------------------------------------------------------------------------- /Logan/Server/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | hello, logan 2 | 3 | -------------------------------------------------------------------------------- /Logan/WebSDK/.eslintignore: -------------------------------------------------------------------------------- 1 | *.js -------------------------------------------------------------------------------- /Logan/WebSDK/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "rules": { 13 | "semi": [ 14 | "error", 15 | "always" 16 | ], 17 | "quotes": [ 18 | "error", 19 | "single" 20 | ], 21 | "@typescript-eslint/no-explicit-any": 0, 22 | "@typescript-eslint/no-inferrable-types": 0, 23 | "prefer-const": 1, 24 | "@typescript-eslint/ban-ts-ignore": 0, 25 | "@typescript-eslint/no-var-requires": 0, 26 | "space-before-blocks": [ 27 | "warn", 28 | "always" 29 | ], 30 | "keyword-spacing": 1, 31 | "comma-dangle": [ 32 | "error", 33 | "never" 34 | ] 35 | } 36 | } -------------------------------------------------------------------------------- /Logan/WebSDK/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | node_modules/ 4 | dist/ 5 | build/ 6 | package-lock.json 7 | coverage/ -------------------------------------------------------------------------------- /Logan/WebSDK/.npmrc: -------------------------------------------------------------------------------- 1 | registry="https://registry.npmjs.org/" -------------------------------------------------------------------------------- /Logan/WebSDK/img/logan_web_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/WebSDK/img/logan_web_structure.png -------------------------------------------------------------------------------- /Logan/WebSDK/img/logan_web_structure_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/WebSDK/img/logan_web_structure_en.png -------------------------------------------------------------------------------- /Logan/WebSDK/img/logan_web_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/WebSDK/img/logan_web_workflow.png -------------------------------------------------------------------------------- /Logan/WebSDK/img/logan_web_workflow_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/Logan/WebSDK/img/logan_web_workflow_en.png -------------------------------------------------------------------------------- /Logan/WebSDK/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | '^.+\\.ts?$': 'ts-jest' 4 | }, 5 | collectCoverageFrom: [ 6 | 'src/**/*.ts' 7 | ], 8 | moduleFileExtensions: ['ts', 'js'], 9 | }; -------------------------------------------------------------------------------- /Logan/WebSDK/src/global-config.ts: -------------------------------------------------------------------------------- 1 | import { GlobalConfig } from './interface'; 2 | const DEFAULT_TRY_TIMES = 3; 3 | const Noop = (): void => { /* Noop */ }; 4 | let globalConfig: GlobalConfig = { 5 | logTryTimes: DEFAULT_TRY_TIMES, 6 | errorHandler: Noop, 7 | succHandler: Noop 8 | }; 9 | function validOrBackup ( 10 | param: any, 11 | type: 'string' | 'number' | 'function', 12 | backup: any 13 | ): any { 14 | return typeof param === type ? param : backup; 15 | } 16 | export default { 17 | set: (configOb: GlobalConfig): void => { 18 | globalConfig = { 19 | publicKey: validOrBackup(configOb.publicKey, 'string', undefined), 20 | logTryTimes: validOrBackup( 21 | configOb.logTryTimes, 22 | 'number', 23 | DEFAULT_TRY_TIMES 24 | ), 25 | reportUrl: validOrBackup(configOb.reportUrl, 'string', undefined), 26 | dbName: validOrBackup(configOb.dbName, 'string', undefined), 27 | errorHandler: validOrBackup( 28 | configOb.errorHandler, 29 | 'function', 30 | Noop 31 | ), 32 | succHandler: validOrBackup( 33 | configOb.succHandler, 34 | 'function', 35 | Noop 36 | ) 37 | }; 38 | }, 39 | get: (propertyKey: keyof GlobalConfig): any => { 40 | return globalConfig[propertyKey]; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Logan/WebSDK/src/lib/ajax.ts: -------------------------------------------------------------------------------- 1 | import XHR from './xhr'; 2 | export default async (url: string, data?: any, withCredentials?: boolean, type?: 'GET' | 'POST' | string, headers?: Record): Promise => { 3 | return new Promise((resolve, reject) => { 4 | XHR({ 5 | url, 6 | type: type || 'GET', 7 | data, 8 | withCredentials: !!withCredentials, 9 | headers: headers, 10 | success: (responseText: any) => { 11 | resolve(responseText); 12 | }, 13 | fail: (err: string) => { 14 | reject(new Error(err || 'Request failed')); 15 | } 16 | }); 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /Logan/WebSDK/src/lib/xhr.ts: -------------------------------------------------------------------------------- 1 | const NOOP = function (): void { /* Noop */ }; 2 | interface XHROpts { 3 | url: string; 4 | type: 'GET' | 'POST' | string; 5 | withCredentials: boolean; 6 | success?: Function; 7 | fail?: Function; 8 | headers?: any; 9 | data?: any; 10 | } 11 | export default function (opts: XHROpts): XMLHttpRequest { 12 | const useXDomainRequest: boolean = 'XDomainRequest' in window; 13 | const req = useXDomainRequest 14 | ? new (window as any).XDomainRequest() 15 | : new XMLHttpRequest(); 16 | req.open(opts.type || 'GET', opts.url, true); 17 | req.success = opts.success || NOOP; 18 | req.fail = opts.fail || NOOP; 19 | req.withCredentials = opts.withCredentials; 20 | if (useXDomainRequest) { 21 | req.onload = opts.success || NOOP; 22 | req.onerror = opts.fail || NOOP; 23 | req.onprogress = NOOP; 24 | } else { 25 | req.onreadystatechange = function (): void { 26 | if (req.readyState === 4) { 27 | const status = req.status; 28 | if (status >= 200) { 29 | opts.success && opts.success(req.responseText); 30 | } else { 31 | opts.fail && opts.fail(`Request failed, status: ${status}, responseText: ${req.responseText}`); 32 | } 33 | } 34 | }; 35 | } 36 | if (opts.type === 'POST') { 37 | if (opts.headers && !useXDomainRequest) { 38 | for (const key in opts.headers) { 39 | req.setRequestHeader(key, opts.headers[key]); 40 | } 41 | } 42 | req.send(opts.data); 43 | } else { 44 | req.send(); 45 | } 46 | return req; 47 | } 48 | -------------------------------------------------------------------------------- /Logan/WebSDK/src/log-manager.ts: -------------------------------------------------------------------------------- 1 | import Config from './global-config'; 2 | let logTryQuota: number = Config.get('logTryTimes') as number; 3 | function errorTrigger (): void { 4 | if (logTryQuota > 0) { 5 | logTryQuota--; 6 | } 7 | } 8 | 9 | function canSave (): boolean { 10 | return logTryQuota > 0; 11 | } 12 | 13 | function resetQuota (): void { 14 | logTryQuota = Config.get('logTryTimes') as number; 15 | } 16 | 17 | export default { 18 | errorTrigger, 19 | canSave, 20 | resetQuota 21 | }; 22 | -------------------------------------------------------------------------------- /Logan/WebSDK/src/logan-operation-queue.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @file This file is to arrange logan operations in queue, in order to avoid parallel async writing operations on db which may cause race condition problems. 3 | * 4 | * 由于Logan的log方法涉及LoganDB日志存储空间大小的改写、report方法在做增量上报时涉及本地日志数据的删除,这些方法被异步执行时可能会发生竞态条件导致DB内数据不准确,进而导致已存储的日志大小远超过存储空间限制、在触发上报时段写入的日志被删除这类问题,因此Logan需要内部维护该执行列表,确保这些异步方法按序一一执行。 5 | * 6 | */ 7 | const loganOperationQueue: PromiseItem[] = []; 8 | let operationRunning: boolean = false; 9 | interface PromiseItem { 10 | asyncF: Function; 11 | resolution: Function; 12 | rejection: Function; 13 | } 14 | async function loganOperationsRecursion (): Promise { 15 | while (loganOperationQueue.length > 0 && !operationRunning) { 16 | const nextOperation = loganOperationQueue.shift() as PromiseItem; 17 | operationRunning = true; 18 | try { 19 | const result = await nextOperation.asyncF(); 20 | nextOperation.resolution(result); 21 | } catch (e) { 22 | nextOperation.rejection(e); 23 | } 24 | operationRunning = false; /* eslint-disable-line */ // No need to worry require-atomic-updates here. 25 | loganOperationsRecursion(); 26 | } 27 | } 28 | export function invokeInQueue (asyncF: Function): Promise { 29 | return new Promise((resolve, reject) => { 30 | loganOperationQueue.push({ 31 | asyncF, 32 | resolution: resolve, 33 | rejection: reject 34 | }); 35 | loganOperationsRecursion(); 36 | }); 37 | } -------------------------------------------------------------------------------- /Logan/WebSDK/src/node-index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Run in node env for isomorphic projects. logan-web will do nothing if its function is called in node env. 3 | */ 4 | /* eslint-disable */ 5 | var NOOP = function () { /* Noop */ }; 6 | module.exports = { 7 | initConfig: NOOP, 8 | log: NOOP, 9 | logWithEncryption: NOOP, 10 | report: NOOP, 11 | customLog: NOOP, 12 | ResultMsg: {} 13 | }; -------------------------------------------------------------------------------- /Logan/WebSDK/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build", 4 | "target": "es5", 5 | "module": "esnext", 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "lib": [ 9 | "es2016", 10 | "dom" 11 | ], 12 | "declaration": true 13 | }, 14 | "include": [ 15 | "src/**/*" 16 | ], 17 | "exclude": [ 18 | "node_modules", 19 | "tests/**/*" 20 | ] 21 | } -------------------------------------------------------------------------------- /Logan/WebSDK/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | const STATIC_JS = 'js'; 3 | const PUBLIC_PATH = './' + STATIC_JS + '/'; 4 | const DEMO_PATH = './demo'; 5 | module.exports = [ 6 | { 7 | mode: 'production', 8 | entry: { 9 | 'logan-web': ['./build/index.js'] 10 | }, 11 | output: { 12 | path: path.join(__dirname, DEMO_PATH, STATIC_JS), 13 | publicPath: PUBLIC_PATH, 14 | filename: '[name].js', 15 | chunkFilename: '[name].[chunkhash].js', 16 | library: 'Logan', 17 | libraryTarget: 'umd', 18 | crossOriginLoading: 'anonymous' 19 | }, 20 | resolve: { 21 | extensions: ['.ts', '.js'] 22 | }, 23 | module: { 24 | rules: [] 25 | }, 26 | devServer: { 27 | hot: true, 28 | contentBase: DEMO_PATH, 29 | publicPath: PUBLIC_PATH, 30 | open: true 31 | } 32 | // , devtool: 'source-map' 33 | } 34 | ]; 35 | -------------------------------------------------------------------------------- /Logan/clogan.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Logan/clogan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Logan/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 4 | # db config 5 | sed -i "s/host/db/" $dir/Server/src/main/resources/db.properties 6 | sed -i "s/port/3306/" $dir/Server/src/main/resources/db.properties 7 | sed -i "s/database/logan/" $dir/Server/src/main/resources/db.properties 8 | sed -i "s/=username/=logan/" $dir/Server/src/main/resources/db.properties 9 | sed -i "s/=password/=logan/" $dir/Server/src/main/resources/db.properties 10 | 11 | # front 12 | sed -i "s/registry.npmjs.org/registry.npmmirror.com/" $dir/LoganSite/.npmrc 13 | cp $dir/LoganSite/.env.development.example $dir/LoganSite/.env.development 14 | 15 | docker-compose --file=$dir/docker-compose.yaml up -d --build 16 | -------------------------------------------------------------------------------- /Logan/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | backend: 4 | build: 5 | context: Server 6 | restart: always 7 | networks: 8 | - logan-network 9 | depends_on: 10 | - db 11 | links: 12 | - db 13 | ports: 14 | - 8888:8080 15 | db: 16 | image: mysql:8.0 17 | restart: always 18 | environment: 19 | MYSQL_DATABASE: logan 20 | MYSQL_USER: logan 21 | MYSQL_PASSWORD: logan 22 | MYSQL_RANDOM_ROOT_PASSWORD: yes 23 | volumes: 24 | - ./.data/mysql/data:/var/lib/mysql 25 | ports: 26 | - 23306:3306 27 | networks: 28 | - logan-network 29 | db-migrate: 30 | image: migrate/migrate 31 | networks: 32 | - logan-network 33 | volumes: 34 | - ./scripts/migration/mysql:/etc/migrations 35 | command: 36 | [ 37 | "-source", 38 | "file:///etc/migrations", 39 | "-database", 40 | "mysql://logan:logan@tcp(db:3306)/logan", 41 | "up" 42 | ] 43 | depends_on: 44 | - db 45 | links: 46 | - db 47 | restart: "no" 48 | phpmyadmin: 49 | image: phpmyadmin:5.2 50 | depends_on: 51 | - db 52 | links: 53 | - db 54 | ports: 55 | - 10050:80 56 | environment: 57 | - PMA_HOST=db 58 | - PMA_USER=logan 59 | - PMA_PASSWORD=logan 60 | networks: 61 | - logan-network 62 | frontend: 63 | build: 64 | context: LoganSite 65 | ports: 66 | - 3000:80 67 | networks: 68 | - logan-network 69 | depends_on: 70 | - backend 71 | networks: 72 | logan-network: 73 | driver: bridge 74 | -------------------------------------------------------------------------------- /Logan/mbedtls/include/.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | *.sln 3 | *.vcxproj 4 | mbedtls/check_config 5 | -------------------------------------------------------------------------------- /Logan/mbedtls/include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON) 2 | 3 | if(INSTALL_MBEDTLS_HEADERS) 4 | 5 | file(GLOB headers "mbedtls/*.h") 6 | 7 | install(FILES ${headers} 8 | DESTINATION include/mbedtls 9 | PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) 10 | 11 | endif(INSTALL_MBEDTLS_HEADERS) 12 | -------------------------------------------------------------------------------- /Logan/mbedtls/include/mbedtls/net.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file net.h 3 | * 4 | * \brief Deprecated header file that includes mbedtls/net_sockets.h 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | * 23 | * \deprecated Superseded by mbedtls/net_sockets.h 24 | */ 25 | 26 | #if !defined(MBEDTLS_DEPRECATED_REMOVED) 27 | #include "mbedtls/net_sockets.h" 28 | #if defined(MBEDTLS_DEPRECATED_WARNING) 29 | #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" 30 | #endif /* MBEDTLS_DEPRECATED_WARNING */ 31 | #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 32 | -------------------------------------------------------------------------------- /Logan/mbedtls/library/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | libmbed* 3 | *.sln 4 | *.vcxproj 5 | -------------------------------------------------------------------------------- /Logan/mbedtls/library/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Version information 3 | * 4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 | * SPDX-License-Identifier: Apache-2.0 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | * not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * This file is part of mbed TLS (https://tls.mbed.org) 20 | */ 21 | 22 | #if !defined(MBEDTLS_CONFIG_FILE) 23 | #include "mbedtls/config.h" 24 | #else 25 | #include MBEDTLS_CONFIG_FILE 26 | #endif 27 | 28 | #if defined(MBEDTLS_VERSION_C) 29 | 30 | #include "mbedtls/version.h" 31 | #include 32 | 33 | unsigned int mbedtls_version_get_number() 34 | { 35 | return( MBEDTLS_VERSION_NUMBER ); 36 | } 37 | 38 | void mbedtls_version_get_string( char *string ) 39 | { 40 | memcpy( string, MBEDTLS_VERSION_STRING, 41 | sizeof( MBEDTLS_VERSION_STRING ) ); 42 | } 43 | 44 | void mbedtls_version_get_string_full( char *string ) 45 | { 46 | memcpy( string, MBEDTLS_VERSION_STRING_FULL, 47 | sizeof( MBEDTLS_VERSION_STRING_FULL ) ); 48 | } 49 | 50 | #endif /* MBEDTLS_VERSION_C */ 51 | -------------------------------------------------------------------------------- /Logan/scripts/migration/mysql/1_init.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `logan_task`; 2 | DROP TABLE IF EXISTS `logan_log_detail`; 3 | DROP TABLE IF EXISTS `web_task`; 4 | DROP TABLE IF EXISTS `web_detail`; -------------------------------------------------------------------------------- /img/before_logan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/before_logan.png -------------------------------------------------------------------------------- /img/logan_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_arch.png -------------------------------------------------------------------------------- /img/logan_arch_paltform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_arch_paltform.png -------------------------------------------------------------------------------- /img/logan_case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_case.png -------------------------------------------------------------------------------- /img/logan_detail.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_detail.gif -------------------------------------------------------------------------------- /img/logan_list_filter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_list_filter.gif -------------------------------------------------------------------------------- /img/logan_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_logo.png -------------------------------------------------------------------------------- /img/logan_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_process.png -------------------------------------------------------------------------------- /img/logan_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Meituan-Dianping/Logan/41bc5d0ea5f86e2e42b6ae5deaa7168aaef14961/img/logan_system.png --------------------------------------------------------------------------------