├── .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
--------------------------------------------------------------------------------