Repository: aregtech/areg-sdk
Branch: master
Commit: 78be212621a2
Files: 1112
Total size: 18.1 MB
Directory structure:
gitextract_3lusol1m/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── config.yml
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── accessibility-bot.yml
│ ├── cmake.yml
│ ├── codeql-analysis.yml
│ ├── msbuild.yml
│ └── validate-pr.yml
├── .gitignore
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── Releases.md
├── areg-sdk.sln
├── areg.cmake
├── conf/
│ ├── README.md
│ ├── cmake/
│ │ ├── clang.cmake
│ │ ├── common.cmake
│ │ ├── functions.cmake
│ │ ├── gnu.cmake
│ │ ├── install.cmake
│ │ ├── msvc.cmake
│ │ ├── setup.cmake
│ │ └── user.cmake
│ ├── exports/
│ │ ├── areg.pc.in
│ │ ├── aregextend.pc.in
│ │ ├── areglogger.pc.in
│ │ ├── config.cmake.in
│ │ ├── example/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── ReadMe.md
│ │ │ ├── example.cpp
│ │ │ └── toolchains/
│ │ │ ├── clang-linux-arm32.cmake
│ │ │ ├── clang-linux-arm64.cmake
│ │ │ ├── clang-linux-x64.cmake
│ │ │ ├── clang-linux-x86.cmake
│ │ │ ├── clang-macos-arm64.cmake
│ │ │ ├── clang-macos-x64.cmake
│ │ │ ├── clang-win-x64.cmake
│ │ │ ├── clang-win-x86.cmake
│ │ │ ├── gnu-linux-arm32.cmake
│ │ │ ├── gnu-linux-arm64.cmake
│ │ │ ├── gnu-linux-x64.cmake
│ │ │ ├── gnu-linux-x86.cmake
│ │ │ ├── msvc-win-x64.cmake
│ │ │ └── msvc-win-x86.cmake
│ │ ├── logcollector.service.in
│ │ ├── logcollector.service.install.bat.in
│ │ ├── logcollector.service.install.sh.in
│ │ ├── logcollector.service.uninstall.bat.in
│ │ ├── logcollector.service.uninstall.sh.in
│ │ ├── mtrouter.service.in
│ │ ├── mtrouter.service.install.bat.in
│ │ ├── mtrouter.service.install.sh.in
│ │ ├── mtrouter.service.uninstall.bat.in
│ │ ├── mtrouter.service.uninstall.sh.in
│ │ ├── tech.areg.logcollector.plist.in
│ │ └── tech.areg.mtrouter.plist.in
│ └── msvc/
│ ├── compile.props
│ ├── project.props
│ ├── project_defaults.props
│ └── user.props
├── docs/
│ ├── DEVELOP.md
│ ├── HOWTO.md
│ ├── HelloService.md
│ ├── HelloService.siml
│ ├── POSIX.md
│ ├── README.md
│ ├── Sample.siml
│ ├── Sample.xsd
│ ├── ServiceInterface.md
│ ├── USECASES.md
│ ├── WIN32.md
│ ├── templates/
│ │ ├── Readme.md
│ │ ├── contributors.yml
│ │ ├── msvc-dynamic-lib.vcxproj
│ │ ├── msvc-dynamic-lib.vcxproj.filters
│ │ ├── msvc-exe.vcxproj
│ │ ├── msvc-exe.vcxproj.filters
│ │ ├── msvc-static-lib.vcxproj
│ │ └── msvc-static-lib.vcxproj.filters
│ └── wiki/
│ ├── 01a-areg-package.md
│ ├── 01b-cmake-build.md
│ ├── 01c-msvc-build.md
│ ├── 01d-wsl-build.md
│ ├── 02a-quick-project-setup.md
│ ├── 02b-cmake-integrate.md
│ ├── 02c-msvc-integrate.md
│ ├── 02d-cmake-config.md
│ ├── 02e-cmake-functions.md
│ ├── 02f-preprocessor-definitions.md
│ ├── 03a-mtrouter.md
│ ├── 04a-logging-config.md
│ ├── 04b-logging-develop.md
│ ├── 04c-logobserver.md
│ ├── 04d-logcollector.md
│ ├── 05a-persistence-syntax.md
│ ├── 06a-areg-sdk-tools.md
│ ├── 06b-code-generator.md
│ ├── 06c-build-lusan.md
│ ├── 06d-setup-lusan.md
│ ├── 06e-lusan-service-interface.md
│ ├── 06f-lusan-live-logging.md
│ ├── 06g-lusan-offline-logging.md
│ ├── 07a-troubleshooting-wsl-update.md
│ ├── 07b-troubleshooting-cmake-linux-builds.md
│ ├── 07c-troubleshooting-integration.md
│ ├── 08a-examples-and-tests.md
│ └── README.md
├── examples/
│ ├── 01_minimalrpc/
│ │ ├── 01_generated.vcxproj
│ │ ├── 01_generated.vcxproj.filters
│ │ ├── 01_minimalrpc.vcxproj
│ │ ├── 01_minimalrpc.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── services/
│ │ │ └── HelloService.siml
│ │ └── src/
│ │ └── main.cpp
│ ├── 02_minimalipc/
│ │ ├── 02_consumeripc.vcxproj
│ │ ├── 02_consumeripc.vcxproj.filters
│ │ ├── 02_generated.vcxproj
│ │ ├── 02_generated.vcxproj.filters
│ │ ├── 02_provideripc.vcxproj
│ │ ├── 02_provideripc.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── services/
│ │ │ └── HelloService.siml
│ │ └── src/
│ │ ├── consumeripc.cpp
│ │ └── provideripc.cpp
│ ├── 03_helloservice/
│ │ ├── 03_clientproc.vcxproj
│ │ ├── 03_clientproc.vcxproj.filters
│ │ ├── 03_generated.vcxproj
│ │ ├── 03_generated.vcxproj.filters
│ │ ├── 03_onethread.vcxproj
│ │ ├── 03_onethread.vcxproj.filters
│ │ ├── 03_serviceproc.vcxproj
│ │ ├── 03_serviceproc.vcxproj.filters
│ │ ├── 03_twothreads.vcxproj
│ │ ├── 03_twothreads.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── src/
│ │ │ ├── ClientComponent.cpp
│ │ │ ├── ClientComponent.hpp
│ │ │ ├── ServiceComponent.cpp
│ │ │ └── ServiceComponent.hpp
│ │ ├── multiprocess/
│ │ │ ├── clientproc/
│ │ │ │ └── src/
│ │ │ │ └── main.cpp
│ │ │ └── serviceproc/
│ │ │ └── src/
│ │ │ └── main.cpp
│ │ ├── onethread/
│ │ │ └── src/
│ │ │ └── main.cpp
│ │ ├── services/
│ │ │ └── HelloService.siml
│ │ └── twothreads/
│ │ └── src/
│ │ └── main.cpp
│ ├── 04_hellothread/
│ │ ├── 04_hellothread.vcxproj
│ │ ├── 04_hellothread.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 05_buffer/
│ │ ├── 05_buffer.vcxproj
│ │ ├── 05_buffer.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 06_file/
│ │ ├── 06_file.vcxproj
│ │ ├── 06_file.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 07_logging/
│ │ ├── 07_logging.vcxproj
│ │ ├── 07_logging.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 08_timer/
│ │ ├── 08_timer.vcxproj
│ │ ├── 08_timer.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 09_threads/
│ │ ├── 09_threads.vcxproj
│ │ ├── 09_threads.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 10_sync/
│ │ ├── 10_sync.vcxproj
│ │ ├── 10_sync.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 11_service/
│ │ ├── 11_service.vcxproj
│ │ ├── 11_service.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ ├── ServicingComponent.cpp
│ │ ├── ServicingComponent.hpp
│ │ └── main.cpp
│ ├── 12_svcmulti/
│ │ ├── 12_svcmulti.vcxproj
│ │ ├── 12_svcmulti.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ ├── ServicingComponent.cpp
│ │ ├── ServicingComponent.hpp
│ │ └── main.cpp
│ ├── 13_locsvc/
│ │ ├── 13_generated.vcxproj
│ │ ├── 13_generated.vcxproj.filters
│ │ ├── 13_locservice.vcxproj
│ │ ├── 13_locservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── locservice/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ ├── ServicingComponent.cpp
│ │ │ ├── ServicingComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloWorld.siml
│ ├── 14_locmesh/
│ │ ├── 14_generated.vcxproj
│ │ ├── 14_generated.vcxproj.filters
│ │ ├── 14_localmesh.vcxproj
│ │ ├── 14_localmesh.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── locsvcmesh/
│ │ │ └── src/
│ │ │ ├── ClientComponent.cpp
│ │ │ ├── ClientComponent.hpp
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ ├── ServiceHelloWorld.cpp
│ │ │ ├── ServiceHelloWorld.hpp
│ │ │ ├── ServicingComponents.cpp
│ │ │ ├── ServicingComponents.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloWorld.siml
│ ├── 15_pubsvc/
│ │ ├── 15_generated.vcxproj
│ │ ├── 15_generated.vcxproj.filters
│ │ ├── 15_pubclient.vcxproj
│ │ ├── 15_pubclient.vcxproj.filters
│ │ ├── 15_pubservice.vcxproj
│ │ ├── 15_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── ServicingComponent.cpp
│ │ │ ├── ServicingComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloWorld.siml
│ ├── 16_pubmesh/
│ │ ├── 16_common.vcxproj
│ │ ├── 16_common.vcxproj.filters
│ │ ├── 16_generated.vcxproj
│ │ ├── 16_generated.vcxproj.filters
│ │ ├── 16_pubclients.vcxproj
│ │ ├── 16_pubclients.vcxproj.filters
│ │ ├── 16_pubservice.vcxproj
│ │ ├── 16_pubservice.vcxproj.filters
│ │ ├── 16_pubsvcmesh.vcxproj
│ │ ├── 16_pubsvcmesh.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── src/
│ │ │ ├── LocalHelloWorldClient.cpp
│ │ │ ├── LocalHelloWorldClient.hpp
│ │ │ ├── LocalHelloWorldService.cpp
│ │ │ ├── LocalHelloWorldService.hpp
│ │ │ ├── NECommon.hpp
│ │ │ ├── PublicHelloWorldClient.cpp
│ │ │ ├── PublicHelloWorldClient.hpp
│ │ │ ├── PublicHelloWorldService.cpp
│ │ │ └── PublicHelloWorldService.hpp
│ │ ├── pubclients/
│ │ │ └── src/
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── PublicServiceComponent.cpp
│ │ │ ├── PublicServiceComponent.hpp
│ │ │ └── main.cpp
│ │ ├── pubsvcmesh/
│ │ │ └── src/
│ │ │ └── main.cpp
│ │ └── services/
│ │ ├── LocalHelloWorld.siml
│ │ ├── PublicHelloWorld.siml
│ │ └── SystemShutdown.siml
│ ├── 17_pubtraffic/
│ │ ├── 17_generated.vcxproj
│ │ ├── 17_generated.vcxproj.filters
│ │ ├── 17_pubclient.vcxproj
│ │ ├── 17_pubclient.vcxproj.filters
│ │ ├── 17_pubservice.vcxproj
│ │ ├── 17_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── NECommon.hpp
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── TrafficLightClient.cpp
│ │ │ ├── TrafficLightClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── TrafficLightService.cpp
│ │ │ ├── TrafficLightService.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── SimpleTrafficLight.siml
│ ├── 18_pubworker/
│ │ ├── 18_common.vcxproj
│ │ ├── 18_common.vcxproj.filters
│ │ ├── 18_generated.vcxproj
│ │ ├── 18_generated.vcxproj.filters
│ │ ├── 18_pubclient.vcxproj
│ │ ├── 18_pubclient.vcxproj.filters
│ │ ├── 18_pubservice.vcxproj
│ │ ├── 18_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ ├── NECommon.hpp
│ │ │ └── PatientInfoEvent.hpp
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── HardwareWorkerConsumer.cpp
│ │ │ ├── HardwareWorkerConsumer.hpp
│ │ │ ├── PatientClient.cpp
│ │ │ ├── PatientClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── PatientService.cpp
│ │ │ ├── PatientService.hpp
│ │ │ ├── PatientServiceWorkerConsumer.cpp
│ │ │ ├── PatientServiceWorkerConsumer.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── PatientInformation.siml
│ ├── 19_pubfsm/
│ │ ├── 19_generated.vcxproj
│ │ ├── 19_generated.vcxproj.filters
│ │ ├── 19_pubclient.vcxproj
│ │ ├── 19_pubclient.vcxproj.filters
│ │ ├── 19_pubservice.vcxproj
│ │ ├── 19_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── NECommon.hpp
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── TrafficLightClient.cpp
│ │ │ ├── TrafficLightClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── IETrafficLightActionHandler.cpp
│ │ │ ├── IETrafficLightActionHandler.hpp
│ │ │ ├── NETrafficLightFSM.cpp
│ │ │ ├── NETrafficLightFSM.hpp
│ │ │ ├── PowerControllerClient.cpp
│ │ │ ├── PowerControllerClient.hpp
│ │ │ ├── TrafficLightFSM.cpp
│ │ │ ├── TrafficLightFSM.hpp
│ │ │ ├── TrafficLightService.cpp
│ │ │ ├── TrafficLightService.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ ├── PowerManager.siml
│ │ └── TrafficController.siml
│ ├── 20_winchat/
│ │ ├── 20_chatter.vcxproj
│ │ ├── 20_chatter.vcxproj.filters
│ │ ├── 20_generated.vcxproj
│ │ ├── 20_generated.vcxproj.filters
│ │ ├── 20_register.vcxproj
│ │ ├── 20_register.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── chatter/
│ │ │ ├── DistrbutedApp.cpp
│ │ │ ├── DistrbutedApp.hpp
│ │ │ ├── NEDistributedApp.cpp
│ │ │ ├── NEDistributedApp.hpp
│ │ │ ├── res/
│ │ │ │ ├── chatter.rc
│ │ │ │ ├── chatter.rc2
│ │ │ │ ├── resource.h
│ │ │ │ ├── stdafx.cpp
│ │ │ │ ├── stdafx.h
│ │ │ │ └── targetver.h
│ │ │ ├── services/
│ │ │ │ ├── CentralMessaging.cpp
│ │ │ │ ├── CentralMessaging.hpp
│ │ │ │ ├── ChatParticipantService.cpp
│ │ │ │ ├── ChatParticipantService.hpp
│ │ │ │ ├── ChatPrticipantHandler.cpp
│ │ │ │ ├── ChatPrticipantHandler.hpp
│ │ │ │ ├── ConnectionHandler.cpp
│ │ │ │ ├── ConnectionHandler.hpp
│ │ │ │ ├── ConnectionList.cpp
│ │ │ │ ├── ConnectionList.hpp
│ │ │ │ ├── ConnectionService.cpp
│ │ │ │ ├── ConnectionService.hpp
│ │ │ │ ├── DirectChatService.cpp
│ │ │ │ ├── DirectChatService.hpp
│ │ │ │ ├── DirectConnectionClient.cpp
│ │ │ │ ├── DirectConnectionClient.hpp
│ │ │ │ ├── DirectConnectionService.cpp
│ │ │ │ ├── DirectConnectionService.hpp
│ │ │ │ ├── DirectMessagingClient.cpp
│ │ │ │ ├── DirectMessagingClient.hpp
│ │ │ │ ├── NetworkSetup.cpp
│ │ │ │ └── NetworkSetup.hpp
│ │ │ └── ui/
│ │ │ ├── DistributedDialog.cpp
│ │ │ ├── DistributedDialog.hpp
│ │ │ ├── PageChat.cpp
│ │ │ ├── PageChat.hpp
│ │ │ ├── PageConnections.cpp
│ │ │ ├── PageConnections.hpp
│ │ │ ├── PageMessaging.cpp
│ │ │ ├── PageMessaging.hpp
│ │ │ ├── PageNetworkSetup.cpp
│ │ │ └── PageNetworkSetup.hpp
│ │ ├── common/
│ │ │ └── NECommon.hpp
│ │ ├── register/
│ │ │ ├── CentralApp.cpp
│ │ │ ├── CentralApp.hpp
│ │ │ ├── NECentralApp.cpp
│ │ │ ├── NECentralApp.hpp
│ │ │ ├── res/
│ │ │ │ ├── register.rc
│ │ │ │ ├── register.rc2
│ │ │ │ ├── resource.h
│ │ │ │ ├── stdafx.cpp
│ │ │ │ ├── stdafx.h
│ │ │ │ └── targetver.h
│ │ │ ├── services/
│ │ │ │ ├── ConnectionManager.cpp
│ │ │ │ └── ConnectionManager.hpp
│ │ │ └── ui/
│ │ │ ├── CentralDialog.cpp
│ │ │ ├── CentralDialog.hpp
│ │ │ ├── PageBrokerSetup.cpp
│ │ │ ├── PageBrokerSetup.hpp
│ │ │ ├── PageConnections.cpp
│ │ │ └── PageConnections.hpp
│ │ └── services/
│ │ ├── CentralMessager.siml
│ │ ├── ConnectionManager.siml
│ │ ├── DirectConnection.siml
│ │ └── DirectMessager.siml
│ ├── 21_locwatchdog/
│ │ ├── 21_generated.vcxproj
│ │ ├── 21_generated.vcxproj.filters
│ │ ├── 21_locservice.vcxproj
│ │ ├── 21_locservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── locservice/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ ├── ServicingComponent.cpp
│ │ │ ├── ServicingComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloWatchdog.siml
│ ├── 22_pubwatchdog/
│ │ ├── 22_generated.vcxproj
│ │ ├── 22_generated.vcxproj.filters
│ │ ├── 22_pubclient.vcxproj
│ │ ├── 22_pubclient.vcxproj.filters
│ │ ├── 22_pubservice.vcxproj
│ │ ├── 22_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── NECommon.hpp
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── ServicingComponent.cpp
│ │ │ ├── ServicingComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloWatchdog.siml
│ ├── 23_pubdatarate/
│ │ ├── 23_generated.vcxproj
│ │ ├── 23_generated.vcxproj.filters
│ │ ├── 23_pubclient.vcxproj
│ │ ├── 23_pubclient.vcxproj.filters
│ │ ├── 23_pubservice.vcxproj
│ │ ├── 23_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ ├── NELargeData.hpp
│ │ │ └── SimpleBitmap.hpp
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── NEUtilities.cpp
│ │ │ ├── NEUtilities.hpp
│ │ │ ├── ServicingComponent.cpp
│ │ │ ├── ServicingComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── LargeData.siml
│ ├── 24_pubunblock/
│ │ ├── 24_generated.vcxproj
│ │ ├── 24_generated.vcxproj.filters
│ │ ├── 24_pubclient.vcxproj
│ │ ├── 24_pubclient.vcxproj.filters
│ │ ├── 24_pubservice.vcxproj
│ │ ├── 24_pubservice.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── pubclient/
│ │ │ └── src/
│ │ │ ├── ServiceClient.cpp
│ │ │ ├── ServiceClient.hpp
│ │ │ └── main.cpp
│ │ ├── pubservice/
│ │ │ └── src/
│ │ │ ├── ServiceComponent.cpp
│ │ │ ├── ServiceComponent.hpp
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── HelloUnblock.siml
│ ├── 25_pubsub/
│ │ ├── 25_generated.vcxproj
│ │ ├── 25_generated.vcxproj.filters
│ │ ├── 25_publisher.vcxproj
│ │ ├── 25_publisher.vcxproj.filters
│ │ ├── 25_subscriber.vcxproj
│ │ ├── 25_subscriber.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── publisher/
│ │ │ └── src/
│ │ │ ├── Publisher.cpp
│ │ │ ├── Publisher.hpp
│ │ │ └── main.cpp
│ │ ├── services/
│ │ │ └── PubSub.siml
│ │ └── subscriber/
│ │ └── src/
│ │ ├── Subscriber.cpp
│ │ ├── Subscriber.hpp
│ │ └── main.cpp
│ ├── 26_pubsubmix/
│ │ ├── 26_common.vcxproj
│ │ ├── 26_common.vcxproj.filters
│ │ ├── 26_generated.vcxproj
│ │ ├── 26_generated.vcxproj.filters
│ │ ├── 26_pubsubctrl.vcxproj
│ │ ├── 26_pubsubctrl.vcxproj.filters
│ │ ├── 26_pubsubdyn.vcxproj
│ │ ├── 26_pubsubdyn.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── common/
│ │ │ └── src/
│ │ │ ├── NECommon.cpp
│ │ │ ├── NECommon.hpp
│ │ │ ├── PubSubMixed.cpp
│ │ │ ├── PubSubMixed.hpp
│ │ │ ├── Publisher.cpp
│ │ │ ├── Publisher.hpp
│ │ │ ├── Subscriber.cpp
│ │ │ └── Subscriber.hpp
│ │ ├── pubsubctrl/
│ │ │ └── src/
│ │ │ ├── PubSubController.cpp
│ │ │ ├── PubSubController.hpp
│ │ │ └── main.cpp
│ │ ├── pubsubdyn/
│ │ │ └── src/
│ │ │ └── main.cpp
│ │ └── services/
│ │ └── PubSubMix.siml
│ ├── 27_pubsubmulti/
│ │ ├── 27_generated.vcxproj
│ │ ├── 27_generated.vcxproj.filters
│ │ ├── 27_publisher.vcxproj
│ │ ├── 27_publisher.vcxproj.filters
│ │ ├── 27_subscribermulti.vcxproj
│ │ ├── 27_subscribermulti.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ ├── publisher/
│ │ │ └── src/
│ │ │ ├── Publisher.cpp
│ │ │ ├── Publisher.hpp
│ │ │ └── main.cpp
│ │ ├── services/
│ │ │ └── PubSub.siml
│ │ └── subscribermulti/
│ │ └── src/
│ │ ├── NECommon.hpp
│ │ ├── Subscriber.cpp
│ │ ├── Subscriber.hpp
│ │ ├── SubscriberBase.cpp
│ │ ├── SubscriberBase.hpp
│ │ ├── SubscriberSecond.cpp
│ │ ├── SubscriberSecond.hpp
│ │ └── main.cpp
│ ├── 28_stlsync/
│ │ ├── 28_stlsync.vcxproj
│ │ ├── 28_stlsync.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── 29_syncevent/
│ │ ├── 29_syncevent.vcxproj
│ │ ├── 29_syncevent.vcxproj.filters
│ │ ├── CMakeLists.txt
│ │ ├── ReadMe.md
│ │ └── src/
│ │ └── main.cpp
│ ├── CMakeLists.txt
│ ├── README.md
│ ├── dummy/
│ │ ├── dummy.cpp
│ │ ├── dummy.vcxproj
│ │ └── dummy.vcxproj.filters
│ └── examples_generate.bat
├── framework/
│ ├── CMakeLists.txt
│ ├── README.md
│ ├── areg/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── appbase/
│ │ │ ├── Application.hpp
│ │ │ ├── NEApplication.hpp
│ │ │ └── private/
│ │ │ ├── Application.cpp
│ │ │ ├── CMakeLists.txt
│ │ │ ├── NEApplication.cpp
│ │ │ ├── configure.cpp
│ │ │ ├── configure.hpp
│ │ │ ├── posix/
│ │ │ │ └── ApplicationPosix.cpp
│ │ │ └── win32/
│ │ │ └── ApplicationWin32.cpp
│ │ ├── base/
│ │ │ ├── BufferStreamBase.hpp
│ │ │ ├── Containers.hpp
│ │ │ ├── DateTime.hpp
│ │ │ ├── File.hpp
│ │ │ ├── FileBase.hpp
│ │ │ ├── FileBuffer.hpp
│ │ │ ├── GEGlobal.h
│ │ │ ├── GEMacros.h
│ │ │ ├── GESwitches.h
│ │ │ ├── GETypes.h
│ │ │ ├── IEByteBuffer.hpp
│ │ │ ├── IECursorPosition.hpp
│ │ │ ├── IEGenericObject.hpp
│ │ │ ├── IEIOStream.hpp
│ │ │ ├── IESyncObject.hpp
│ │ │ ├── IEThreadConsumer.hpp
│ │ │ ├── Identifier.hpp
│ │ │ ├── NECommon.hpp
│ │ │ ├── NEMath.hpp
│ │ │ ├── NEMemory.hpp
│ │ │ ├── NESocket.hpp
│ │ │ ├── NEString.hpp
│ │ │ ├── NEUtilities.hpp
│ │ │ ├── Object.hpp
│ │ │ ├── Process.hpp
│ │ │ ├── RemoteMessage.hpp
│ │ │ ├── RuntimeClassID.hpp
│ │ │ ├── RuntimeObject.hpp
│ │ │ ├── SharedBuffer.hpp
│ │ │ ├── Socket.hpp
│ │ │ ├── SocketAccepted.hpp
│ │ │ ├── SocketClient.hpp
│ │ │ ├── SocketServer.hpp
│ │ │ ├── String.hpp
│ │ │ ├── SyncObjects.hpp
│ │ │ ├── TEArrayList.hpp
│ │ │ ├── TEFixedArray.hpp
│ │ │ ├── TEHashMap.hpp
│ │ │ ├── TELinkedList.hpp
│ │ │ ├── TEMap.hpp
│ │ │ ├── TEProperty.hpp
│ │ │ ├── TEResourceListMap.hpp
│ │ │ ├── TEResourceMap.hpp
│ │ │ ├── TERingStack.hpp
│ │ │ ├── TERuntimeResourceMap.hpp
│ │ │ ├── TESortedLinkedList.hpp
│ │ │ ├── TEStack.hpp
│ │ │ ├── TEString.hpp
│ │ │ ├── TETemplateBase.hpp
│ │ │ ├── Thread.hpp
│ │ │ ├── ThreadAddress.hpp
│ │ │ ├── ThreadLocalStorage.hpp
│ │ │ ├── Version.hpp
│ │ │ ├── WideString.hpp
│ │ │ └── private/
│ │ │ ├── BufferPosition.cpp
│ │ │ ├── BufferPosition.hpp
│ │ │ ├── BufferStreamBase.cpp
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Containers.cpp
│ │ │ ├── DateTime.cpp
│ │ │ ├── File.cpp
│ │ │ ├── FileBase.cpp
│ │ │ ├── FileBuffer.cpp
│ │ │ ├── GEGlobal.cpp
│ │ │ ├── IEByteBuffer.cpp
│ │ │ ├── IECursorPosition.cpp
│ │ │ ├── IEGenericObject.cpp
│ │ │ ├── IEIOStream.cpp
│ │ │ ├── IESyncObject.cpp
│ │ │ ├── IEThreadConsumer.cpp
│ │ │ ├── Identifier.cpp
│ │ │ ├── NECommon.cpp
│ │ │ ├── NEDebug.cpp
│ │ │ ├── NEDebug.hpp
│ │ │ ├── NEMath.cpp
│ │ │ ├── NEMemory.cpp
│ │ │ ├── NESocket.cpp
│ │ │ ├── NEString.cpp
│ │ │ ├── NEUtilities.cpp
│ │ │ ├── Object.cpp
│ │ │ ├── Process.cpp
│ │ │ ├── ReadConverter.cpp
│ │ │ ├── ReadConverter.hpp
│ │ │ ├── RemoteMessage.cpp
│ │ │ ├── RuntimeBase.cpp
│ │ │ ├── RuntimeBase.hpp
│ │ │ ├── RuntimeClassID.cpp
│ │ │ ├── RuntimeObject.cpp
│ │ │ ├── SharedBuffer.cpp
│ │ │ ├── Socket.cpp
│ │ │ ├── SocketAccepted.cpp
│ │ │ ├── SocketClient.cpp
│ │ │ ├── SocketServer.cpp
│ │ │ ├── String.cpp
│ │ │ ├── SyncObjects.cpp
│ │ │ ├── Thread.cpp
│ │ │ ├── ThreadAddress.cpp
│ │ │ ├── ThreadLocalStorage.cpp
│ │ │ ├── Version.cpp
│ │ │ ├── WideString.cpp
│ │ │ ├── WriteConverter.cpp
│ │ │ ├── WriteConverter.hpp
│ │ │ ├── posix/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── CriticalSectionIX.cpp
│ │ │ │ ├── CriticalSectionIX.hpp
│ │ │ │ ├── FilePosix.cpp
│ │ │ │ ├── IESyncObjectBaseIX.cpp
│ │ │ │ ├── IESyncObjectBaseIX.hpp
│ │ │ │ ├── IEWaitableBaseIX.cpp
│ │ │ │ ├── IEWaitableBaseIX.hpp
│ │ │ │ ├── MutexIX.cpp
│ │ │ │ ├── MutexIX.hpp
│ │ │ │ ├── NEDebugPosix.cpp
│ │ │ │ ├── NESocketPosix.cpp
│ │ │ │ ├── NESyncTypesIX.hpp
│ │ │ │ ├── NEUtilitiesPosix.cpp
│ │ │ │ ├── ProcessPosix.cpp
│ │ │ │ ├── SpinLockIX.cpp
│ │ │ │ ├── SpinLockIX.hpp
│ │ │ │ ├── SyncLockAndWaitIX.cpp
│ │ │ │ ├── SyncLockAndWaitIX.hpp
│ │ │ │ ├── SyncObjectsPosix.cpp
│ │ │ │ ├── ThreadPosix.cpp
│ │ │ │ ├── WaitableEventIX.cpp
│ │ │ │ ├── WaitableEventIX.hpp
│ │ │ │ ├── WaitableMutexIX.cpp
│ │ │ │ ├── WaitableMutexIX.hpp
│ │ │ │ ├── WaitableSemaphoreIX.cpp
│ │ │ │ ├── WaitableSemaphoreIX.hpp
│ │ │ │ ├── WaitableTimerIX.cpp
│ │ │ │ └── WaitableTimerIX.hpp
│ │ │ └── win32/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── FileWin32.cpp
│ │ │ ├── NEDebugWin32.cpp
│ │ │ ├── NESocketWin32.cpp
│ │ │ ├── NEUtilitiesWin32.cpp
│ │ │ ├── ProcessWin32.cpp
│ │ │ ├── SpinLockWin32.cpp
│ │ │ ├── SpinLockWin32.hpp
│ │ │ ├── SyncObjectsWin32.cpp
│ │ │ └── ThreadWin32.cpp
│ │ ├── component/
│ │ │ ├── Channel.hpp
│ │ │ ├── Component.hpp
│ │ │ ├── ComponentAddress.hpp
│ │ │ ├── ComponentLoader.hpp
│ │ │ ├── ComponentThread.hpp
│ │ │ ├── DispatcherThread.hpp
│ │ │ ├── Event.hpp
│ │ │ ├── EventData.hpp
│ │ │ ├── EventDataStream.hpp
│ │ │ ├── EventDispatcher.hpp
│ │ │ ├── IEEventConsumer.hpp
│ │ │ ├── IEEventRouter.hpp
│ │ │ ├── IEProxyListener.hpp
│ │ │ ├── IERemoteEventConsumer.hpp
│ │ │ ├── IETimerConsumer.hpp
│ │ │ ├── IEWorkerThreadConsumer.hpp
│ │ │ ├── NERegistry.hpp
│ │ │ ├── NEService.hpp
│ │ │ ├── NotificationEvent.hpp
│ │ │ ├── ProxyAddress.hpp
│ │ │ ├── ProxyBase.hpp
│ │ │ ├── ProxyEvent.hpp
│ │ │ ├── RemoteEventFactory.hpp
│ │ │ ├── RequestEvents.hpp
│ │ │ ├── ResponseEvents.hpp
│ │ │ ├── ServiceAddress.hpp
│ │ │ ├── ServiceItem.hpp
│ │ │ ├── ServiceRequestEvent.hpp
│ │ │ ├── ServiceResponseEvent.hpp
│ │ │ ├── StreamableEvent.hpp
│ │ │ ├── StubAddress.hpp
│ │ │ ├── StubBase.hpp
│ │ │ ├── StubEvent.hpp
│ │ │ ├── TEEvent.hpp
│ │ │ ├── Timer.hpp
│ │ │ ├── TimerBase.hpp
│ │ │ ├── WorkerThread.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Channel.cpp
│ │ │ ├── ClientInfo.cpp
│ │ │ ├── ClientInfo.hpp
│ │ │ ├── ClientList.cpp
│ │ │ ├── ClientList.hpp
│ │ │ ├── Component.cpp
│ │ │ ├── ComponentAddress.cpp
│ │ │ ├── ComponentInfo.cpp
│ │ │ ├── ComponentInfo.hpp
│ │ │ ├── ComponentLoader.cpp
│ │ │ ├── ComponentThread.cpp
│ │ │ ├── DispatcherThread.cpp
│ │ │ ├── Event.cpp
│ │ │ ├── EventConsumerMap.cpp
│ │ │ ├── EventConsumerMap.hpp
│ │ │ ├── EventData.cpp
│ │ │ ├── EventDataStream.cpp
│ │ │ ├── EventDispatcher.cpp
│ │ │ ├── EventDispatcherBase.cpp
│ │ │ ├── EventDispatcherBase.hpp
│ │ │ ├── EventQueue.cpp
│ │ │ ├── EventQueue.hpp
│ │ │ ├── ExitEvent.cpp
│ │ │ ├── ExitEvent.hpp
│ │ │ ├── IEEventConsumer.cpp
│ │ │ ├── IEEventDispatcher.cpp
│ │ │ ├── IEEventDispatcher.hpp
│ │ │ ├── IEEventRouter.cpp
│ │ │ ├── IEProxyListener.cpp
│ │ │ ├── IEQueueListener.cpp
│ │ │ ├── IEQueueListener.hpp
│ │ │ ├── IERemoteEventConsumer.cpp
│ │ │ ├── IETimerConsumer.cpp
│ │ │ ├── IEWorkerThreadConsumer.cpp
│ │ │ ├── NERegistry.cpp
│ │ │ ├── NEService.cpp
│ │ │ ├── NotificationEvent.cpp
│ │ │ ├── ProxyAddress.cpp
│ │ │ ├── ProxyBase.cpp
│ │ │ ├── ProxyConnectEvent.cpp
│ │ │ ├── ProxyConnectEvent.hpp
│ │ │ ├── ProxyEvent.cpp
│ │ │ ├── RemoteEventFactory.cpp
│ │ │ ├── RequestEvents.cpp
│ │ │ ├── ResponseEvents.cpp
│ │ │ ├── ServerInfo.cpp
│ │ │ ├── ServerInfo.hpp
│ │ │ ├── ServerList.cpp
│ │ │ ├── ServerList.hpp
│ │ │ ├── ServiceAddress.cpp
│ │ │ ├── ServiceItem.cpp
│ │ │ ├── ServiceManager.cpp
│ │ │ ├── ServiceManager.hpp
│ │ │ ├── ServiceManagerEventProcessor.cpp
│ │ │ ├── ServiceManagerEventProcessor.hpp
│ │ │ ├── ServiceManagerEvents.cpp
│ │ │ ├── ServiceManagerEvents.hpp
│ │ │ ├── ServiceRequestEvent.cpp
│ │ │ ├── ServiceResponseEvent.cpp
│ │ │ ├── SortedEventStack.cpp
│ │ │ ├── SortedEventStack.hpp
│ │ │ ├── StreamableEvent.cpp
│ │ │ ├── StubAddress.cpp
│ │ │ ├── StubBase.cpp
│ │ │ ├── StubConnectEvent.cpp
│ │ │ ├── StubConnectEvent.hpp
│ │ │ ├── StubEvent.cpp
│ │ │ ├── TEEvent.cpp
│ │ │ ├── Timer.cpp
│ │ │ ├── TimerBase.cpp
│ │ │ ├── TimerEventData.cpp
│ │ │ ├── TimerEventData.hpp
│ │ │ ├── TimerManager.cpp
│ │ │ ├── TimerManager.hpp
│ │ │ ├── TimerManagerBase.cpp
│ │ │ ├── TimerManagerBase.hpp
│ │ │ ├── TimerManagerEvent.cpp
│ │ │ ├── TimerManagerEvent.hpp
│ │ │ ├── Watchdog.cpp
│ │ │ ├── Watchdog.hpp
│ │ │ ├── WatchdogManager.cpp
│ │ │ ├── WatchdogManager.hpp
│ │ │ ├── WorkerThread.cpp
│ │ │ ├── posix/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── TimerBasePosix.cpp
│ │ │ │ ├── TimerManagerPosix.cpp
│ │ │ │ ├── TimerPosix.cpp
│ │ │ │ ├── TimerPosix.hpp
│ │ │ │ └── WatchdogManagerPosix.cpp
│ │ │ └── win32/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── TimerBaseWin32.cpp
│ │ │ ├── TimerManagerWin32.cpp
│ │ │ └── WatchdogManagerWin32.cpp
│ │ ├── ipc/
│ │ │ ├── ClientConnection.hpp
│ │ │ ├── ConnectionConfiguration.hpp
│ │ │ ├── IERemoteMessageHandler.hpp
│ │ │ ├── IEServiceConnectionConsumer.hpp
│ │ │ ├── IEServiceConnectionProvider.hpp
│ │ │ ├── IEServiceRegisterConsumer.hpp
│ │ │ ├── IEServiceRegisterProvider.hpp
│ │ │ ├── NERemoteService.hpp
│ │ │ ├── SendMessageEvent.hpp
│ │ │ ├── ServerConnectionBase.hpp
│ │ │ ├── ServiceClientConnectionBase.hpp
│ │ │ ├── ServiceEvent.hpp
│ │ │ ├── ServiceEventConsumerBase.hpp
│ │ │ ├── SocketConnectionBase.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── ClientConnection.cpp
│ │ │ ├── ClientReceiveThread.cpp
│ │ │ ├── ClientReceiveThread.hpp
│ │ │ ├── ClientSendThread.cpp
│ │ │ ├── ClientSendThread.hpp
│ │ │ ├── ConnectionConfiguration.cpp
│ │ │ ├── IERemoteMessageHandler.cpp
│ │ │ ├── IEServiceConnectionConsumer.cpp
│ │ │ ├── IEServiceConnectionProvider.cpp
│ │ │ ├── IEServiceRegisterConsumer.cpp
│ │ │ ├── IEServiceRegisterProvider.cpp
│ │ │ ├── NEConnection.cpp
│ │ │ ├── NEConnection.hpp
│ │ │ ├── NERemoteService.cpp
│ │ │ ├── RouterClient.cpp
│ │ │ ├── RouterClient.hpp
│ │ │ ├── SendMessageEvent.cpp
│ │ │ ├── ServerConnectionBase.cpp
│ │ │ ├── ServiceClientConnectionBase.cpp
│ │ │ ├── ServiceEvent.cpp
│ │ │ ├── ServiceEventConsumerBase.cpp
│ │ │ └── SocketConnectionBase.cpp
│ │ ├── logging/
│ │ │ ├── GELog.h
│ │ │ ├── IELogDatabaseEngine.hpp
│ │ │ ├── LogConfiguration.hpp
│ │ │ ├── LogScope.hpp
│ │ │ ├── NELogging.hpp
│ │ │ ├── ScopeMessage.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── DatabaseLogger.cpp
│ │ │ ├── DatabaseLogger.hpp
│ │ │ ├── DebugOutputLogger.cpp
│ │ │ ├── DebugOutputLogger.hpp
│ │ │ ├── FileLogger.cpp
│ │ │ ├── FileLogger.hpp
│ │ │ ├── IELogDatabaseEngine.cpp
│ │ │ ├── LayoutManager.cpp
│ │ │ ├── LayoutManager.hpp
│ │ │ ├── Layouts.cpp
│ │ │ ├── Layouts.hpp
│ │ │ ├── LogConfiguration.cpp
│ │ │ ├── LogEventProcessor.cpp
│ │ │ ├── LogEventProcessor.hpp
│ │ │ ├── LogManager.cpp
│ │ │ ├── LogManager.hpp
│ │ │ ├── LogMessage.cpp
│ │ │ ├── LogMessage.hpp
│ │ │ ├── LogScope.cpp
│ │ │ ├── LoggerBase.cpp
│ │ │ ├── LoggerBase.hpp
│ │ │ ├── LoggingEvent.cpp
│ │ │ ├── LoggingEvent.hpp
│ │ │ ├── NELogOptions.cpp
│ │ │ ├── NELogOptions.hpp
│ │ │ ├── NELogging.cpp
│ │ │ ├── NetTcpLogger.cpp
│ │ │ ├── NetTcpLogger.hpp
│ │ │ ├── ScopeController.cpp
│ │ │ ├── ScopeController.hpp
│ │ │ ├── ScopeMessage.cpp
│ │ │ ├── ScopeNodeBase.cpp
│ │ │ ├── ScopeNodeBase.hpp
│ │ │ ├── ScopeNodes.cpp
│ │ │ └── ScopeNodes.hpp
│ │ ├── persist/
│ │ │ ├── ConfigManager.hpp
│ │ │ ├── IEConfigurationListener.hpp
│ │ │ ├── IEDatabaseEngine.hpp
│ │ │ ├── NEPersistence.hpp
│ │ │ ├── Property.hpp
│ │ │ ├── PropertyKey.hpp
│ │ │ ├── PropertyValue.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── ConfigManager.cpp
│ │ │ ├── IEConfigurationListener.cpp
│ │ │ ├── IEDatabaseEngine.cpp
│ │ │ ├── NEPersistence.cpp
│ │ │ ├── Property.cpp
│ │ │ ├── PropertyKey.cpp
│ │ │ └── PropertyValue.cpp
│ │ ├── resources/
│ │ │ ├── areg.init
│ │ │ ├── areg.rc
│ │ │ ├── areg_post_build.bat
│ │ │ └── resource.h
│ │ └── system/
│ │ ├── GEPlatform.h
│ │ ├── posix/
│ │ │ └── GEPosix.h
│ │ └── windows/
│ │ └── GEWindows.h
│ ├── areg.vcxproj
│ ├── areg.vcxproj.filters
│ ├── aregextend/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── console/
│ │ │ ├── Console.hpp
│ │ │ ├── OptionParser.hpp
│ │ │ ├── SystemServiceConsole.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Console.cpp
│ │ │ ├── OptionParser.cpp
│ │ │ ├── SystemServiceConsole.cpp
│ │ │ ├── ansi/
│ │ │ │ └── ConsoleAnsi.cpp
│ │ │ ├── ncurses/
│ │ │ │ └── ConsoleNcurses.cpp
│ │ │ └── win32/
│ │ │ └── ConsoleWin32.cpp
│ │ ├── db/
│ │ │ ├── LogSqliteDatabase.hpp
│ │ │ ├── SqliteDatabase.hpp
│ │ │ ├── SqliteRow.hpp
│ │ │ ├── SqliteStatement.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LogSqliteDatabase.cpp
│ │ │ ├── SqliteDatabase.cpp
│ │ │ ├── SqliteRow.cpp
│ │ │ └── SqliteStatement.cpp
│ │ ├── resources/
│ │ │ ├── aregextend.rc
│ │ │ └── resource.h
│ │ └── service/
│ │ ├── DataRateHelper.hpp
│ │ ├── IEServiceConnectionHandler.hpp
│ │ ├── NESystemService.hpp
│ │ ├── ServerConnection.hpp
│ │ ├── ServiceApplicationBase.hpp
│ │ ├── ServiceCommunicatonBase.hpp
│ │ ├── SystemServiceBase.hpp
│ │ └── private/
│ │ ├── CMakeLists.txt
│ │ ├── DataRateHelper.cpp
│ │ ├── IEServiceConnectionHandler.cpp
│ │ ├── NESystemService.cpp
│ │ ├── ServerConnection.cpp
│ │ ├── ServerReceiveThread.cpp
│ │ ├── ServerReceiveThread.hpp
│ │ ├── ServerSendThread.cpp
│ │ ├── ServerSendThread.hpp
│ │ ├── ServiceApplicationBase.cpp
│ │ ├── ServiceCommunicatonBase.cpp
│ │ ├── SystemServiceBase.cpp
│ │ ├── posix/
│ │ │ └── ServiceApplicationBasePosix.cpp
│ │ └── win32/
│ │ └── ServiceApplicationBaseWin32.cpp
│ ├── aregextend.vcxproj
│ ├── aregextend.vcxproj.filters
│ ├── areglogger/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── client/
│ │ │ ├── LogObserverApi.h
│ │ │ ├── LogObserverBase.hpp
│ │ │ ├── LogObserverSwitches.h
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LogObserverApi.cpp
│ │ │ ├── LogObserverBase.cpp
│ │ │ ├── LoggerClient.cpp
│ │ │ ├── LoggerClient.hpp
│ │ │ ├── ObserverMessageProcessor.cpp
│ │ │ └── ObserverMessageProcessor.hpp
│ │ └── resources/
│ │ ├── areglogger.def
│ │ ├── areglogger.rc
│ │ └── resource.h
│ ├── areglogger.vcxproj
│ ├── areglogger.vcxproj.filters
│ ├── logcollector/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── app/
│ │ │ ├── LogCollector.hpp
│ │ │ ├── NELogCollectorSettings.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LogCollector.cpp
│ │ │ ├── LogCollectorConsoleService.cpp
│ │ │ ├── LogCollectorConsoleService.hpp
│ │ │ ├── NELogCollectorSettings.cpp
│ │ │ ├── posix/
│ │ │ │ └── LogCollectorPosix.cpp
│ │ │ └── win32/
│ │ │ └── LogCollectorWin32.cpp
│ │ ├── resources/
│ │ │ ├── Readme.md
│ │ │ ├── logcollector.rc
│ │ │ ├── logcollector.service
│ │ │ ├── logcollector.service.install.bat
│ │ │ ├── logcollector.service.uninstall.bat
│ │ │ ├── logcollector_post_build.bat
│ │ │ ├── resource.h
│ │ │ ├── targetver.h
│ │ │ └── tech.areg.logcollector.plist
│ │ └── service/
│ │ ├── LogCollectorServerService.hpp
│ │ └── private/
│ │ ├── CMakeLists.txt
│ │ ├── LogCollectorMessageProcessor.cpp
│ │ ├── LogCollectorMessageProcessor.hpp
│ │ └── LogCollectorServerService.cpp
│ ├── logcollector.vcxproj
│ ├── logcollector.vcxproj.filters
│ ├── logobserver/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── app/
│ │ │ ├── LogObserver.hpp
│ │ │ ├── NELogObserverSettings.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LogObserver.cpp
│ │ │ ├── NELogObserverSettings.cpp
│ │ │ ├── posix/
│ │ │ │ └── LogObserverPosix.cpp
│ │ │ └── win32/
│ │ │ └── LogObserverWin32.cpp
│ │ └── resources/
│ │ ├── logobserver.rc
│ │ ├── resource.h
│ │ └── targetver.h
│ ├── logobserver.vcxproj
│ ├── logobserver.vcxproj.filters
│ ├── mtrouter/
│ │ ├── CMakeLists.txt
│ │ ├── Readme.md
│ │ ├── app/
│ │ │ ├── MultitargetRouter.hpp
│ │ │ ├── NEMultitargetRouterSettings.hpp
│ │ │ └── private/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── MultitargetRouter.cpp
│ │ │ ├── NEMultitargetRouterSettings.cpp
│ │ │ ├── RouterConsoleService.cpp
│ │ │ ├── RouterConsoleService.hpp
│ │ │ ├── posix/
│ │ │ │ └── MultitargetRouterPosix.cpp
│ │ │ └── win32/
│ │ │ └── MultitargetRouterWin32.cpp
│ │ ├── resources/
│ │ │ ├── Readme.md
│ │ │ ├── mtrouter.rc
│ │ │ ├── mtrouter.service
│ │ │ ├── mtrouter.service.install.bat
│ │ │ ├── mtrouter.service.uninstall.bat
│ │ │ ├── mtrouter_post_build.bat
│ │ │ ├── resource.h
│ │ │ ├── targetver.h
│ │ │ └── tech.areg.mtrouter.plist
│ │ └── service/
│ │ ├── RouterServerService.hpp
│ │ └── private/
│ │ ├── CMakeLists.txt
│ │ ├── ListServiceProxies.cpp
│ │ ├── ListServiceProxies.hpp
│ │ ├── RouterServerService.cpp
│ │ ├── ServiceProxy.cpp
│ │ ├── ServiceProxy.hpp
│ │ ├── ServiceRegistry.cpp
│ │ ├── ServiceRegistry.hpp
│ │ ├── ServiceStub.cpp
│ │ └── ServiceStub.hpp
│ ├── mtrouter.vcxproj
│ └── mtrouter.vcxproj.filters
├── msvc_setup.props
├── nuget.config
├── tests/
│ ├── CMakeLists.txt
│ ├── areg-unit-tests.vcxproj
│ ├── areg-unit-tests.vcxproj.filters
│ ├── packages.config
│ └── units/
│ ├── CMakeLists.txt
│ ├── DateTimeTest.cpp
│ ├── FileTest.cpp
│ ├── GUnitTest.cpp
│ ├── GUnitTest.hpp
│ ├── LogScopesTest.cpp
│ ├── NEStringTest.cpp
│ ├── OptionParserTest.cpp
│ ├── StringUtilsTest.cpp
│ ├── TEArrayListTest.cpp
│ ├── TEFixedArrayTest.cpp
│ ├── TEHashMapTest.cpp
│ ├── TELinkedListTest.cpp
│ ├── TEMapTest.cpp
│ ├── TEPropertyTest.cpp
│ ├── TERingStackTest.cpp
│ ├── TESortedLinkedListTest.cpp
│ ├── TEStackTest.cpp
│ └── UnitTestUtilities.hpp
├── thirdparty/
│ ├── CMakeLists.txt
│ ├── sqlite3/
│ │ ├── CMakeLists.txt
│ │ ├── LICENSE.txt
│ │ ├── Readme.md
│ │ └── amalgamation/
│ │ ├── shell.c
│ │ ├── sqlite3.c
│ │ ├── sqlite3.h
│ │ └── sqlite3ext.h
│ ├── sqlite3.vcxproj
│ └── sqlite3.vcxproj.filters
└── tools/
├── README.md
├── codegen.jar
├── codegenerate.bat
├── codegenerate.sh
├── setup-project.bat
└── setup-project.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: aregtech
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
- It would be very helpful to get a running example.
- If bug is obvious without an example, please be clear like
1. Open the file '...'
2. Go to line '...'
3. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop or embedded (please complete the following information):**
- OS: [e.g. Ubuntu Linux]
- Version [e.g. 22]
- Hardware [e.g. x86]
- Compiler [e.g. g++]
- AREG SDK version [e.g. 1.0.1]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: aregtech
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/config.yml
================================================
# DCO Bot Configuration
dco:
enabled: true
require:
- pull_request
token: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"
================================================
FILE: .github/pull_request_template.md
================================================
## Summary
## Changes
## Testing
## Notes
## Checklist
Please check the box ( `[x]` ) and sign-off the this PR:
[ ] I have read CONTRIBUTING.md
Signed-off-by: Your Name or GitHub ID (optional email)
================================================
FILE: .github/workflows/accessibility-bot.yml
================================================
name: Accessibility-alt-text-bot
on:
issues:
types: [opened, edited]
pull_request:
types: [opened, edited]
issue_comment:
types: [created, edited]
discussion:
types: [created, edited]
discussion_comment:
types: [created, edited]
permissions:
issues: write
pull-requests: write
discussions: write
jobs:
accessibility_alt_text_bot:
name: Check alt text is set on issue or pull requests
runs-on: ubuntu-latest
if: ${{ github.event.issue || github.event.pull_request || github.event.discussion }}
steps:
- name: Get action 'github/accessibility-alt-text-bot'
uses: github/accessibility-alt-text-bot@v1.7.2 # Set to latest
================================================
FILE: .github/workflows/cmake.yml
================================================
name: CMake
on:
push: # Keep empty to run on each branch when push the code. Otherwise use branches: [ master ]
branches: [ master ]
pull_request: # Set to master to run only when merge with master branch
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Linux.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
jobs:
build-tests:
name: ${{matrix.config.name}}
runs-on: ${{matrix.config.os}}
strategy:
fail-fast: false
matrix:
config: # Create matrix with combinations
# compile Areg engine as a shared library with GNU g++ / gcc on Ubuntu Linux, enable Areg extensions and logs
- { name : linux-gnu-shared-ext-log,
os : ubuntu-latest,
lib : shared,
family: gnu,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test : OFF
}
# compile Areg engine as a shared library with GNU g++ / gcc on Ubuntu Linux, enable Areg extensions and no logs
- { name : linux-gnu-shared-ext-nolog,
os : ubuntu-latest,
lib : shared,
family: gnu,
cxx : g++,
cc : gcc,
extend: ON,
logs : OFF,
test : OFF
}
# compile Areg engine as a static library with GNU g++ / gcc on Ubuntu Linux, enable Areg extensions, logs, examples and tests
- { name : linux-gnu-static-all-test,
os : ubuntu-latest,
lib : static,
family: gnu,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test: ON
}
# compile Areg engine as a shared library with GNU g++ / gcc on Ubuntu Linux, enable Areg extensions, logs, examples and tests
- { name : linux-gnu-shared-all-test,
os : ubuntu-latest,
lib : shared,
family: gnu,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a shared library with GNU g++ / gcc on Ubuntu Linux, disable Areg extensions and no logs
- { name : linux-gnu-shared-noext-nolog,
os : ubuntu-latest,
lib : shared,
family: gnu,
cxx : g++,
cc : gcc,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a shared library with clang on Ubuntu Linux, enable Areg extensions and logs
- { name : linux-clang-shared-ext-log,
os : ubuntu-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: ON,
logs : ON,
test : OFF
}
# compile Areg engine as a shared library with clang on Ubuntu Linux, enable Areg extensions and no logs
- { name : linux-clang-shared-ext-nolog,
os : ubuntu-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: ON,
logs : OFF,
test : OFF
}
# compile Areg engine as a static library with clang on Ubuntu Linux, enable Areg extensions, logs, examples and tests
- { name : linux-clang-static-all-test,
os : ubuntu-latest,
lib : static,
family: llvm,
cxx : clang++,
cc : clang,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a static library with clang on Ubuntu Linux, enable Areg extensions, logs, examples and tests
- { name : linux-clang-shared-all-test,
os : ubuntu-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a shared library with clang on Ubuntu Linux, disable Areg extensions and no logs
- { name : linux-clang-shared-noext-nolog,
os : ubuntu-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a shared library with clang on macOS, enable logs and tests, disable Areg extensions
- { name : macos-clang-shared-noext,
os : macos-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : ON,
test : ON
}
# compile Areg engine as a shared library with clang on macOS, enable tests, disable Areg extensions and no logs
- { name : macos-clang-shared-noext-nolog,
os : macos-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : OFF,
test : ON
}
# compile Areg engine as a shared library with clang on macOS, enable tests, disable Areg extensions and no logs
- { name : macos-clang-shared-noext-nolog-notest,
os : macos-latest,
lib : shared,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a static library with clang on macOS, enable logs and tests, disable Areg extensions
- { name : macos-clang-static-noext,
os : macos-latest,
lib : static,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : ON,
test : ON
}
# compile Areg engine as a static library with clang on macOS, enable tests, disable Areg extensions and no logs
- { name : macos-clang-static-noext-nolog,
os : macos-latest,
lib : static,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : OFF,
test : ON
}
# compile Areg engine as a static library with clang on macOS, enable tests, disable Areg extensions and no logs
- { name : macos-clang-static-noext-nolog-notest,
os : macos-latest,
lib : static,
family: llvm,
cxx : clang++,
cc : clang,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a shared with CYGWIN g++ / gcc on Windows, enable Areg extensions and logs
- { name : win-cygwin-shared-ext-log,
os : windows-latest,
lib : shared,
family: cygwin,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test : OFF}
# compile Areg engine as a shared with CYGWIN g++ / gcc on Windows, enable Areg extensions and no logs
- { name : win-cygwin-shared-ext-nolog,
os : windows-latest,
lib : shared,
family: cygwin,
cxx : g++,
cc : gcc,
extend: ON,
logs : OFF,
test : OFF
}
# compile Areg engine as a static with CYGWIN g++ / gcc on Windows, enable Areg extensions, logs, examples and tests
- { name : win-cygwin-static-all-test,
os : windows-latest,
lib : static,
family: cygwin,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a static with CYGWIN g++ / gcc on Windows, enable Areg extensions, logs, examples and tests
- { name : win-cygwin-shared-all-test,
os : windows-latest,
lib : shared,
family: cygwin,
cxx : g++,
cc : gcc,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a shared with CYGWIN g++ / gcc on Windows, disable Areg extensions and no logs
- { name : win-cygwin-shared-noext-nolog,
os : windows-latest,
lib : shared,
family: cygwin,
cxx : g++,
cc : gcc,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a shared library with clang on Windows, enable Areg extensions and logs
- { name : win-clang-shared-ext-log,
os : windows-latest,
lib : shared,
family: llvm,
cxx : clang-cl,
cc : clang-cl,
extend: ON,
logs : ON,
test : OFF
}
# compile Areg engine as a shared library with clang on Windows, enable Areg extensions and no logs
- { name : win-clang-shared-ext-nolog,
os : windows-latest,
lib : shared,
family: llvm,
cxx : clang-cl,
cc : clang-cl,
extend: ON,
logs : OFF,
test : OFF
}
# compile Areg engine as a static library with clang on Windows, enable Areg extensions, logs, examples and tests
- { name : win-clang-static-all-test,
os : windows-latest,
lib : static,
family: llvm,
cxx : clang-cl,
cc : clang-cl,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a static library with clang on Windows, enable Areg extensions, logs, examples and tests
- { name : win-clang-shared-all-test,
os : windows-latest,
lib : shared,
family: llvm,
cxx : clang-cl,
cc : clang-cl,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a shared library with clang on Windows, disable Areg extensions and no logs
- { name : win-clang-shared-noext-nolog,
os : windows-latest,
lib : shared,
family: llvm,
cxx : clang-cl,
cc : clang-cl,
extend: OFF,
logs : OFF,
test : OFF
}
# compile Areg engine as a shared with MSVC on Windows, enable Areg extensions and logs
- { name : win-msvc-shared-ext-log,
os : windows-latest,
lib : shared,
family: msvc,
cxx : cl,
cc : cl,
extend: ON,
logs : ON,
test : OFF
}
# compile Areg engine as a shared with MSVC on Windows, enable Areg extensions and no logs
- { name : win-msvc-shared-ext-nolog,
os : windows-latest,
lib : shared,
family: msvc,
cxx : cl,
cc : cl,
extend: ON,
logs : OFF,
test : OFF
}
# compile Areg engine as a static with MSVC on Windows, enable Areg extensions, logs, examples and tests
- { name : win-msvc-static-all-test,
os : windows-latest,
lib : static,
family: msvc,
cxx : cl,
cc : cl,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a static with MSVC on Windows, enable Areg extensions, logs, examples and tests
- { name : win-msvc-shared-all-test,
os : windows-latest,
lib : shared,
family: msvc,
cxx : cl,
cc : cl,
extend: ON,
logs : ON,
test : ON
}
# compile Areg engine as a shared with MSVC on Windows, enable Areg extensions and logs
- { name : win-msvc-shared-noext-log,
os : windows-latest,
lib : shared,
family: msvc,
cxx : cl,
cc : cl,
extend: OFF,
logs : ON,
test : OFF
}
# compile Areg engine as a shared with MSVC on Windows, enable Areg extensions and no logs
- { name : win-msvc-shared-noext-nolog,
os : windows-latest,
lib : shared,
family: msvc,
cxx : cl,
cc : cl,
extend: OFF,
logs : OFF,
test : OFF
}
steps:
- name: Checkout Areg SDK source codes
uses: actions/checkout@v6
- name: Setup Java JDK to run code generator
uses: actions/setup-java@v5.2.0
with:
java-version: 17
java-package: jre
distribution: temurin
- name: Set cmake cache destination for Linux
if: matrix.config.os == 'ubuntu-latest'
run: |
echo "CACHE_DEST=./product/cache/${{matrix.config.family}}-${{matrix.config.cxx}}" >> "$GITHUB_ENV"
echo "BUILD_DEST=./product/build/${{matrix.config.family}}-${{matrix.config.cxx}}/linux-64-x86_64-release-${{matrix.config.lib}}" >> "$GITHUB_ENV"
echo "INSTALL_DEST=./product/install/${{matrix.config.family}}-${{matrix.config.cxx}}" >> "$GITHUB_ENV"
- name: Set cmake cache destination for macOS
if: matrix.config.os == 'macos-latest'
run: |
ARCH=$(uname -m)
echo "CACHE_DEST=./product/cache/${{matrix.config.family}}-${{matrix.config.cxx}}" >> "$GITHUB_ENV"
echo "BUILD_DEST=./product/build/${{matrix.config.family}}-${{matrix.config.cxx}}/darwin-64-${ARCH}-release-${{matrix.config.lib}}" >> "$GITHUB_ENV"
echo "INSTALL_DEST=./product/install/${{matrix.config.family}}-${{matrix.config.cxx}}" >> "$GITHUB_ENV"
- name: Set cmake cache destination for Windows
if: matrix.config.os == 'windows-latest'
run: |
echo "CACHE_DEST=./product/cache/${{matrix.config.family}}-${{matrix.config.cxx}}" >> $env:GITHUB_ENV
echo "BUILD_DEST=./product/build/${{matrix.config.family}}-${{matrix.config.cxx}}/windows-64-amd64-release-${{matrix.config.lib}}" >> $env:GITHUB_ENV
echo "INSTALL_DEST=./product/install/${{matrix.config.family}}-${{matrix.config.cxx}}" >> $env:GITHUB_ENV
- name: Ensure Xcode CLI Tools
if: matrix.config.os == 'macos-latest'
run: sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
- name: Set Windows PATH environment variable
if: matrix.config.os == 'windows-latest' && matrix.config.family == 'cygwin'
run: echo "PATH=C:\cygwin;C:\cygwin\bin;C:\cygwin\lib;%SYSTEMROOT%\system32;%PATH%" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Install cygwin on Windows
if: matrix.config.os == 'windows-latest' && matrix.config.family == 'cygwin'
uses: cygwin/cygwin-install-action@v6
with:
packages: cmake, dos2unix, flexdll, gcc-g++, git, libncurses-devel, make
install-dir: 'C:\cygwin'
add-to-path: false
work-vol: 'C:'
- name: create build and product directories
working-directory: ${{github.workspace}}
run: |
mkdir build
mkdir product
- name: Configure CMake by selecting compiler family
if: matrix.config.extend == 'ON'
working-directory: ${{github.workspace}}
run: |
cmake -B ${{env.CACHE_DEST}} -DAREG_COMPILER_FAMILY=${{matrix.config.family}} -DAREG_BUILD_TYPE=${{env.BUILD_TYPE}} -DAREG_BINARY=${{matrix.config.lib}} -DAREG_EXTENDED:BOOL=${{matrix.config.extend}} -DAREG_LOGS:BOOL=${{matrix.config.logs}} -DAREG_BUILD_EXAMPLES:BOOL=${{matrix.config.test}} -DAREG_BUILD_TESTS:BOOL=${{matrix.config.test}} -DAREG_INSTALL:BOOL=ON -DAREG_INSTALL_PATH:PATH="${{env.INSTALL_DEST}}"
- name: Configure CMake by selecting compiler name
if: matrix.config.extend == 'OFF'
working-directory: ${{github.workspace}}
run: |
cmake -B ${{env.CACHE_DEST}} -DAREG_COMPILER=${{matrix.config.cc}} -DAREG_BUILD_TYPE=${{env.BUILD_TYPE}} -DAREG_BINARY=${{matrix.config.lib}} -DAREG_EXTENDED:BOOL=${{matrix.config.extend}} -DAREG_LOGS:BOOL=${{matrix.config.logs}} -DAREG_BUILD_EXAMPLES:BOOL=${{matrix.config.test}} -DAREG_BUILD_TESTS:BOOL=${{matrix.config.test}} -DAREG_INSTALL:BOOL=ON -DAREG_INSTALL_PATH:PATH="${{env.INSTALL_DEST}}"
- name: Build with CMake
working-directory: ${{github.workspace}}
# Build your program with the given configuration
run: cmake --build ${{env.CACHE_DEST}} --config Release -j 16
- name: Install with CMake
working-directory: ${{github.workspace}}
# Install the binaries and headers
run: cmake --install ${{env.CACHE_DEST}}
- name: Run Unit Tests. Ignore if unit tests are not compiled
if: matrix.config.test == 'ON'
working-directory: ${{github.workspace}}
run: ctest --test-dir ${{env.CACHE_DEST}} --output-on-failure --output-junit test_results.xml
- name: Copy test artifacts if unit tests fail. Ignore if unit tests are not compiled
if: failure() && matrix.config.test == 'ON'
working-directory: ${{github.workspace}}
shell: bash
run: |
mkdir ./${{matrix.config.name}}/
cp -R ./${{env.BUILD_DEST}}/bin/ ./${{matrix.config.name}}/
cp -R ./${{env.INSTALL_DEST}}/ ./${{matrix.config.name}}/
- name: Upload artifacts if tests fail. Ignore if unit tests are not compiled
if: failure() && matrix.config.test == 'ON'
uses: actions/upload-artifact@v6
with:
name: ${{matrix.config.name}}
path: ./${{matrix.config.name}}/
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '32 22 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Java JDK to run code generator
uses: actions/setup-java@v5.2.0
with:
java-version: 17
java-package: jre
distribution: temurin
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v4
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
================================================
FILE: .github/workflows/msbuild.yml
================================================
name: MSBuild
on:
push: # Keep empty to run on each branch when push the code. Otherwise, use branches: [ master ]
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Path to the solution file relative to the root of the project.
SOLUTION_FILE_PATH: .
# Configuration type to build.
# You can convert this to a build matrix if you need coverage of multiple configuration types.
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
BUILD_CONFIGURATION: Release
permissions:
contents: read
jobs:
build-tests:
name: ${{matrix.config.name}}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
config: # Create matrix with combinations
# Compile for 32-bit platform, enabled Areg extensions and logs
- {name: MSBuild-Win32-ext-log, platform: Win32, extend: 1, logs: 1}
# Compile for 32-bit platform, enabled Areg extensions and no logs
- {name: MSBuild-Win32-ext-nolog, platform: Win32, extend: 1, logs: 0}
# Compile for 32-bit platform, disable Areg extensions and logs
- {name: MSBuild-Win32-noext-log, platform: Win32, extend: 0, logs: 1}
# Compile for 32-bit platform, disable Areg extensions and no logs
- {name: MSBuild-Win32-noext-nolog, platform: Win32, extend: 0, logs: 0}
# Compile for 32-bit platform, enabled Areg extensions and logs
- {name: MSBuild-x64-ext-log, platform: x64, extend: 1, logs: 1}
# Compile for 32-bit platform, enabled Areg extensions and no logs
- {name: MSBuild-x64-ext-nolog, platform: x64, extend: 1, logs: 0}
# Compile for 32-bit platform, disable Areg extensions and logs
- {name: MSBuild-x64-noext-log, platform: x64, extend: 0, logs: 1}
# Compile for 32-bit platform, disable Areg extensions and no logs
- {name: MSBuild-x64-noext-nolog, platform: x64, extend: 0, logs: 0}
steps:
- name: Checkout Areg engine (Areg SDK) source codes
uses: actions/checkout@v6
- name: Setup Java JDK to run code generator
uses: actions/setup-java@v5.2.0
with:
java-version: 17
java-package: jre
distribution: temurin
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Restore NuGet packages
working-directory: ${{github.workspace}}
run: nuget restore ${{env.SOLUTION_FILE_PATH}}
- name: Build areg-sdk solution.
working-directory: ${{github.workspace}}
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /property:Configuration=${{env.BUILD_CONFIGURATION}} /property:Platform=${{matrix.config.platform}} /property:AregExtended=${{matrix.config.extend}} /property:AregLogs=${{matrix.config.logs}} ${{env.SOLUTION_FILE_PATH}} -t:restore,build -p:RestorePackagesConfig=true
================================================
FILE: .github/workflows/validate-pr.yml
================================================
name: PR Validation
on:
pull_request:
types: [opened, edited, reopened, synchronize]
jobs:
pr-check:
runs-on: ubuntu-latest
steps:
- name: Verify PR Checklist
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prBody = context.payload.pull_request.body || '';
const errors = [];
if (!prBody.includes('[x] I have read CONTRIBUTING.md')) {
errors.push('Please check the box confirming you have read CONTRIBUTING.md.');
}
if (!prBody.includes('Signed-off-by:')) {
errors.push('Missing "Signed-off-by:" line in PR.');
}
if (errors.length > 0) {
core.setFailed(errors.join('\n'));
}
================================================
FILE: .gitignore
================================================
*.aps
*.opensdf
*.suo
*.sdf
*.user
*.o
*.obj
*.log
*.stackdump
*.d
*.diff
.git
.metadata
.vs
.vscode
build/*
out/*
product/*
tools/*.zip
areg-sdk.code-workspace
Debug
Release
framework/*/Debug
framework/*/Release
framework/*/.settings
framework/*/.gitignore
examples/*/.gitignore
examples/*/.settings
examples/*/Debug
examples/*/Release
examples/*/*/.gitignore
examples/*/*/.settings
examples/*/*/Debug
examples/*/*/Release
examples/*/*/*/.gitignore
examples/*/*/*/.settings
examples/*/*/*/Debug
examples/*/*/*/Release
CMakeSettings.json
================================================
FILE: CMakeLists.txt
================================================
# ###########################################################################
# CMake options of Areg SDK
# Copyright 2022-2026 Aregtech
# ###########################################################################
cmake_minimum_required(VERSION 3.20.0)
# Areg root directory
set(AREG_SDK_ROOT "${CMAKE_CURRENT_LIST_DIR}")
set(AREG_CMAKE_CONFIG_DIR "${AREG_SDK_ROOT}/conf/cmake")
# Set 'AREG_SDK_ROOT' and optional 'AREG_CMAKE_CONFIG_DIR' variables
# before 'setup.cmake', and include 'setup.cmake'
# before 'project' call.
include(${AREG_CMAKE_CONFIG_DIR}/setup.cmake)
# set CMake tool settings
set(CMAKE_BUILD_TYPE ${AREG_BUILD_TYPE} CACHE STRING "Configuration Type" FORCE)
# Areg SDK project name and version
set(AREG_PROJECT_NAME "areg-sdk")
set(AREG_PROJECT_VERSION "1.9.99.111")
# Project's properties
set(PROJECT_NAME ${AREG_PROJECT_NAME})
set(PROJECT_VERSION ${AREG_PROJECT_VERSION})
project("${PROJECT_NAME}"
VERSION "${PROJECT_VERSION}"
DESCRIPTION "Areg Communication Framework and Tools"
HOMEPAGE_URL "https://areg.tech"
LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# The 'common.cmake' file should be included after 'project' call
include(${AREG_CMAKE_CONFIG_DIR}/common.cmake)
# add a custom command to create output build folders if they are not existing.
# create a dummy project to add as a dependency in all other projects.
# this ensures that the commands to create directories are called first.
add_custom_target(areg-dummy ALL COMMAND ${CMAKE_COMMAND} VERBATIM)
add_custom_command( TARGET areg-dummy PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}"
VERBATIM)
include_directories(${AREG_FRAMEWORK})
include_directories(${AREG_THIRDPARTY})
# build Areg Framework thirdparty software
include(${AREG_THIRDPARTY}/CMakeLists.txt)
if (NOT AREG_SQLITE_FOUND)
add_dependencies(aregsqlite3 areg-dummy)
endif()
# build Areg Framework software
include(${AREG_FRAMEWORK}/CMakeLists.txt)
add_dependencies(areg areg-dummy)
# build optional Areg project examples, if required
if(AREG_BUILD_EXAMPLES)
include(${AREG_EXAMPLES}/CMakeLists.txt)
endif()
# build optional Areg Framework unit tests, if required
if(AREG_BUILD_TESTS)
include(${AREG_TESTS}/CMakeLists.txt)
if (NOT AREG_GTEST_FOUND)
# Set dependency of 'areg-dummy' to make sure
# the build directories are created before the
# 'gtest' libraries are built
add_dependencies(areg-unit-tests areg-dummy)
endif()
else()
option(AREG_GTEST_PACKAGE "Use GTest package" FALSE)
option(AREG_GTEST_FOUND "GTest package found flag" FALSE)
endif()
if (AREG_INSTALL)
include(${AREG_CMAKE_CONFIG_DIR}/install.cmake)
endif()
# Print the configuration status
printAregConfigStatus(
TRUE
"Areg"
"----------------------> Areg project CMake Status Report Begin <-----------------------"
"-----------------------> Areg project CMake Status Report End <------------------------"
)
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
**artak[at]areg.tech**.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# CONTRIBUTING TO Areg SDK
Thank you for your interest in contributing to Areg SDK.
We welcome developers, companies, researchers, and hobbyists who want to help improve the framework.
This guide explains how to contribute, how copyrights work, and what you need to do so your contribution can be accepted.
---
## 1. Code Licensing
All contributions are licensed under:
**Apache License, Version 2.0**
By submitting a pull request or commit, you agree that your contribution is provided under Apache 2.0.
---
## 2. Developer Certificate of Origin (DCO)
To contribute, you must confirm that you have the right to submit the code.
Areg SDK uses the **Developer Certificate of Origin (DCO)**. It is a simple and widely adopted alternative to contributor license agreements.
Every commit must include a `Signed-off-by` line:
```
Signed-off-by: Your Name [email@example.com](mailto:email@example.com)
```
Most Git tools can add this automatically:
```
git commit -s
```
By signing off, you state that your contribution is your original work or that you have permission to submit it.
More information can be found at https://developercertificate.org/
---
## 3. Copyright Headers
You may add a copyright header if you want your name or organization to appear in the source file.
If you prefer not to add a header, the project may include a default header for clarity and consistent licensing.
This does not affect your ownership or your rights in any way.
Example of an optional header:
```cpp
/************************************************************************
* This file is part of the Areg SDK core engine.
* Areg SDK is dual licensed under Apache 2.0 and commercial licenses.
*
* \copyright (c) 2017-2026 Your Name or Aregtech UG
* \file path/to/YourFile.hpp
* \ingroup Areg SDK
* \author Your Full Name or GitHub ID
* \brief Brief description
************************************************************************/
```
Minor edits such as typo fixes, grammar corrections, formatting cleanup, comment updates, CMake changes, and YAML updates do not require contributor copyright headers.
---
## 4. Contribution Guidelines
### a. Reporting Bugs
When reporting an issue, please include:
* steps to reproduce
* expected and actual behavior
* platform and compiler information
### b. Submitting Code
Pull requests should follow these rules:
* one clear improvement per pull request
* keep the existing code style
* include tests when possible
* include a `Signed-off-by` line in every commit
### c. Documentation
Improvements to guides, examples, comments, and general documentation are welcome.
Small corrections only require a Signed-off-by line.
---
## 5. Areas Where Help Is Needed
1. C++17 development such as core framework, features, and services
2. Unit tests and example applications
3. Build systems and cross compilation setups
4. UI and UX improvements for the Areg SDK Tools
5. Technical writing including documentation and guides
---
## 6. Dual Licensing and Commercial Use
Areg SDK is licensed under the Apache License 2.0.
You retain ownership of your contribution, which will always remain available under Apache 2.0.
Project maintainers may also offer Areg SDK under separate commercial terms.
By contributing under the DCO and Apache 2.0, you grant the maintainers an irrevocable right to use, modify, sublicense, and distribute your contribution as part of both the open-source and any commercial editions of Areg SDK.
---
## 7. Code of Conduct
Always communicate respectfully and constructively.
We strive to maintain a welcoming community for everyone.
---
## 8. Questions
If you have any questions about licensing, rights, or the contribution process, open an issue or start a discussion.
We are happy to help you get started.
================================================
FILE: LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2017-2026 Aregtech, UG
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
[](https://github.com/aregtech/areg-sdk/releases/tag/v1.5.0)
[](https://github.com/aregtech/areg-sdk/compare/v1.5.0...master)
[](https://github.com/aregtech/areg-sdk/stargazers)
[](./docs/wiki/README.md)
⭐ **If you find Areg SDK useful, give us a star - it helps the project grow!**
---
Most C++ projects don't fail on algorithms. They fail on **threads, IPC, and brittle integration code**. Areg SDK eliminates this complexity using **Object RPC** to automate communication, unifying async RPC, Pub/Sub, and service discovery. Its self-managed service mesh enables scalable systems across threads, processes, and devices with no manual wiring and no fragile glue code.
*Named after the ancient Armenian word for "Sun", Areg creates a star network where services orbit around a central router - enabling automatic discovery, seamless communication, and fault-tolerant distributed computing.*
---
## Project Status[](#project-status)
---
## Table of Contents[](#table-of-contents)
- [Why Areg SDK](#why-areg-sdk)
- [What is Areg SDK](#what-is-areg-sdk)
- [Getting Started in 5 Minutes](#getting-started-in-5-minutes)
- [Architecture and Core Concepts](#architecture-and-core-concepts)
- [Real-World Use Cases](#real-world-use-cases)
- [Roadmap](#roadmap)
- [Documentation](#documentation)
- [License](#license)
- [Community and Contribution](#community-and-contribution)
> [!IMPORTANT]
> Complete technical documentation, build guides, and integration patterns are available in the [Wiki](./docs/wiki/).
---
## Why Areg SDK[](#why-areg-sdk)
### The Real Cost of Distributed C++
Every C++ developer knows the frustration: threading bugs that appear only in production, race conditions that vanish under debuggers, and IPC code that requires weeks of careful integration. Your algorithms work perfectly, but the scaffolding around them is fragile, time-consuming, and error-prone.
**Ask yourself these 5 questions:**
- [ ] Do threading and synchronization issues slow your development velocity?
- [ ] Does debugging across threads, processes, or devices consume excessive time?
- [ ] Is setting up communication between components complex and error-prone?
- [ ] Do remote failures and reconnections create cascading delays?
- [ ] Would location-transparent services simplify your architecture?
💡 **If you answered "Yes" to 3 or more**, Areg SDK will accelerate your development.
---
### How Areg SDK Solves This
Areg SDK eliminates infrastructure complexity with five core capabilities:
**1. Automated Threading Management**
Thread creation, lifecycle, and message dispatch are fully managed by the framework. You define components and their dependencies - the framework handles threading, synchronization, and safe message passing between threads.
**2. Location-Transparent Services**
Services work identically whether local (same thread), IPC (same machine), or remote (network). Change deployment without changing code.
**3. Self-Managing Service Mesh**
Automatic discovery and routing across threads, processes, and devices. Services find each other with no configuration files, no manual wiring.
**4. Built-In Fault Tolerance**
Components can join or leave dynamically. Watchdogs automatically restart failed threads. Systems stay operational under failure.
**5. Native Observability**
Integrated distributed logging with visual analysis. Per-method execution timing enables performance profiling without external tools.
💡 **Best for:** Embedded to enterprise C++ applications on Linux, macOS and Windows, scaling from resource-constrained devices to high-performance server systems.
⚠️ **Not for:** RTOS (planned), web services, or non-C++ ecosystems.
---
### Areg SDK vs. Alternatives
| Feature | Areg SDK | gRPC / DDS / ZeroMQ |
|-----------------------|----------------------------------|------------------------------------------------------|
| **Setup Complexity** | ✅ Automated, zero boilerplate | ⚠️ Manual configuration, [verbose setup](https://www.innoq.com/en/blog/2024/06/grpc/#whataresomechallengesofworkingwithgrpc) |
| **Threading** | ✅ Automated threading | ⚠️ Manual threading and synchronization |
| **Code Generation** | ✅ Full ORPC automation | ⚠️ [Stubs only](https://grpc.io/docs/what-is-grpc/introduction/#overview), manual dispatch |
| **Service Discovery** | ✅ Built-in mesh management | ✅ DDS: [native](https://opendds.readthedocs.io/en/latest-release/devguide/introduction_to_dds.html#discovery-matching-and-association), ⚠️ gRPC/ZeroMQ: [external](https://stackoverflow.com/questions/59398556/grpc-equivalent-of-wcf-service-discovery) |
| **Fault Recovery** | ✅ Watchdog auto-restart | ✅ DDS: [QoS policies](https://opendds.readthedocs.io/en/latest-release/devguide/quality_of_service.html), ⚠️ gRPC/ZeroMQ: [manual](https://grpc.io/docs/guides/retry/) |
| **Request-Reply** | ✅ Native Object RPC | ✅ gRPC: [RPC calls](https://grpc.io/docs/what-is-grpc/core-concepts/#overview), ⚠️ DDS/ZeroMQ: [topic/pattern](https://zguide.zeromq.org/docs/chapter3/) |
| **Pub/Sub** | ✅ Native Attributes | ✅ DDS: [topics](https://opendds.readthedocs.io/en/latest-release/devguide/built_in_topics.html), ⚠️ gRPC/ZeroMQ: add-ons |
| **API Consistency** | ✅ Identical for threads and IPC | ⚠️ Different APIs for local vs. remote |
| **Logging System** | ✅ Distributed logs + viewer | ⚠️ [Vendor-specific](https://community.rti.com/static/documentation/connext-dds/current/doc/manuals/addon_products/observability/telemetry_data/logs.html) or external tools |
| **Developer Speed** | ✅ Faster via automation | ⚠️ Slower, more boilerplate |
🔹 **Key Differentiators:**
- **Complete automation** - Not just transport, but threading, dispatch, and lifecycle
- **True location transparency** - Same interface whether thread, process, or network
- **Zero configuration** - Services auto-discover, no manual registry setup
- **Integrated stack** - Framework + Router + Tools + Logging in one cohesive SDK
---
## What is Areg SDK[](#what-is-areg-sdk)
**Areg SDK** is a complete toolkit for building service-oriented C++ systems, centered around the **Areg Framework** - a runtime that automates threading, IPC, and service orchestration using **interface-centric Object RPC (ORPC)**.
### The ORPC Model
Unlike traditional RPC that treats remote calls as simple functions, Areg's Object RPC represents services as **stateful objects** with:
- **Methods** - Request-reply interactions
- **Attributes** - Publish-subscribe data with automatic update notifications
- **Events** - Asynchronous notifications across service boundaries
This enables true **service-oriented architecture** where services are logical entities independent of physical location.
---
### What's Inside the SDK
**Core Runtime:**
🔹 **Areg Framework** (`areg`) - The engine that automates threading, IPC, and service mesh
🔹 **Multitarget Router** (`mtrouter`) - Central message router for inter-process and network communication
**Development Tools:**
🔹 **Code Generator** (`codegen.jar`) - Eliminates boilerplate, generates service stubs from interfaces
🔹 **[Lusan GUI](https://github.com/aregtech/areg-sdk-tools)** - Visual service designer and distributed log viewer
**Monitoring & Debug:**
🔹 **Log Collector** (`logcollector`) + **Observer** (`logobserver`) - Distributed logging and real-time analysis
🔹 **Areg Extend** - Additional utilities and extensions
> 📦 **All components** work together seamlessly with no integration glue required.
---
### How Location Transparency Works
With Areg SDK, you:
1. Define service interfaces (methods, attributes, events)
2. Run code generator to create base classes
3. Implement your business logic
4. Load services via model configuration
**The same service code runs:**
- **Multithreaded** - Components in different threads, same process
- **Multiprocess** - Components in different processes, same machine (requires `mtrouter`)
- **Multi-device** - Components across network devices (requires `mtrouter`)
**No code changes required** - just configuration. Example: [`03_helloservice`](./examples/03_helloservice) demonstrates this flexibility.
---
## Architecture and Core Concepts[](#architecture-and-core-concepts)
### Modules Overview
| Module | Purpose | When Required |
|--------|---------|---------------|
| **[Areg Library](./docs/HelloService.md)** (`areg`) | Core framework automating Object RPC, threading, IPC routing, and fault recovery | ✅ Always |
| **[Code Generator](./docs/wiki/03a-code-generator.md)** (`codegen.jar`) | Generates service stubs from interface definitions, eliminating boilerplate | ✅ Build-time |
| **[Multitarget Router](./docs/wiki/05a-mtrouter.md)** (`mtrouter`) | Central message router for inter-process and network communication | ⚠️ IPC/Network only |
| **[Log Collector](./docs/wiki/04d-logcollector.md)** (`logcollector`) | Aggregates distributed logs for monitoring and debugging | ❌ Optional |
| **[Lusan GUI](https://github.com/aregtech/areg-sdk-tools)** (`lusan`) | Visual service designer and log analysis tool | ❌ Optional |
| **[Examples](./examples/README.md)** | Sample projects demonstrating SDK features | ❌ Optional |
---
### Interface-Centric Architecture
Areg's **Object RPC (ORPC)** model treats services as **stateful objects** rather than simple function calls. Applications expose **Service Providers** and interact via **Service Consumers**, with the **Multitarget Router** handling inter-process and network communication.
**Key architectural patterns:**
- **Request-Reply** - Traditional RPC method calls
- **Publish-Subscribe** - Automatic attribute updates across all subscribers
- **Event Broadcasting** - Asynchronous notifications to interested parties
This architecture supports **multithreading**, **multiprocessing**, and **multi-device** systems with consistent low-latency characteristics.
---
### Lusan Development Tool
**Lusan** streamlines service-oriented development with two core capabilities: **visual service design** and **distributed log analysis**.
#### Service Interface Designer
The visual designer enables rapid, error-free service definition with automatic code generation. Define methods, attributes, and events graphically - Lusan generates production-ready C++ code for both providers and consumers.
**Benefits:**
- Visual clarity prevents interface design errors
- Consistent code generation eliminates manual mistakes
- Integrated documentation in the design process
📄 **Learn more:** [Service Interface Design Guide](./docs/wiki/06d-setup-lusan.md)
#### Live and Offline Log Viewer
Lusan's log viewer aggregates logs from multiple processes, supporting both **real-time monitoring** and **offline analysis** of recorded sessions.
**Key capabilities:**
- Real-time log aggregation across processes and devices
- Dynamic scope filtering and priority control at runtime
- Offline session replay for post-mortem debugging
- Performance profiling with per-method execution timing
📄 **Documentation:**
- [Live Log Viewer Guide](./docs/wiki/06f-lusan-live-logging.md) - Real-time monitoring
- [Offline Log Viewer Guide](./docs/wiki/06g-lusan-offline-logging.md) - Session analysis
**In summary**, Lusan unifies service design and runtime observability, accelerating development cycles and enabling safer development of service-oriented systems.
---
## Real-World Use Cases[](#real-world-use-cases)
### Embedded and Edge AI Systems
AI-powered edge devices require coordinating multiple concurrent processes: data acquisition, preprocessing, inference, decision-making, monitoring, and connectivity. Areg SDK lets each stage run as an **independent service** with event-driven communication and automatic thread management.
**Benefits:**
- **Modular pipelines** - Each AI stage (capture, preprocess, infer, decide) is isolated
- **Automatic concurrency** - Framework handles threading and synchronization
- **Real-time responsiveness** - Non-blocking architecture for fast control loops
- **Scalable orchestration** - Distribute AI workloads across devices seamlessly
> [!TIP]
> **See it in action:** [areg-edgeai](https://github.com/aregtech/areg-edgeai) - Real-world Edge AI integration examples
---
### IoT: Mist-to-Cloud Architecture
Traditional IoT architectures stream raw sensor data to distant cloud servers, creating latency, network congestion, and privacy concerns. With Areg SDK, devices form a **mist network** - a mesh of micro-services that process and aggregate data locally before sending refined insights to the cloud.
**Benefits:**
- **Low-latency processing** - Data analyzed at the edge, not in distant datacenters
- **Autonomous operation** - Edge mesh continues working during network outages
- **Enhanced privacy** - Sensitive data stays on-device; only insights leave the edge
- **Reduced cloud costs** - Less data transmission and cloud compute needed
---
### Simulation and Testing Environments
Validating service-oriented systems traditionally requires expensive hardware and complex test environments. Areg SDK enables **Data Layer simulation** in external applications, providing realistic test environments without physical devices. Services appear **location-transparent** to higher layers - tests can't distinguish simulated from real hardware.
**Benefits:**
- **Hardware-independent testing** - Test logic layer without physical devices
- **Continuous integration** - Automated testing without hardware dependencies
- **Fault injection** - Safely simulate failures and test recovery mechanisms
- **Cost reduction** - Eliminate expensive test hardware and lab time
---
### Driverless Device Architecture
Traditional device drivers are slow to develop, complex to maintain, and platform-specific. Areg SDK lets you **expose hardware as portable services**, making devices platform-independent and network-accessible.
**Benefits:**
- **Faster development** - Accelerates prototyping and iteration
- **Platform independence** - Hardware abstracted as services
- **Network accessibility** - Devices accessible from anywhere on network
- **Early validation** - Test hardware integration before driver implementation
---
### Industry 4.0: Smart Manufacturing Systems
Traditional industrial automation relies on proprietary protocols and rigid architectures that make factory reconfiguration expensive and time-consuming. When production lines change, entire systems often require reprogramming. Areg SDK transforms factory components into **modular services** that communicate seamlessly, enabling flexible manufacturing systems that adapt to changing production needs.
**Service types:**
- **Local Services** - Confined within a single process, protecting sensitive data from external access
- **Public Services** - Accessible across processes and devices within the network created by `mtrouter`
**Benefits:**
- **Flexible reconfiguration** - Add or replace equipment without reprogramming entire production lines
- **Protocol independence** - Abstract proprietary industrial protocols behind unified service interfaces
- **Digital twin integration** - Services work identically on physical equipment and simulation environments
- **Predictive maintenance** - Distributed logging enables real-time equipment health monitoring
- **Reduced integration costs** - Modular services eliminate expensive custom integration code
**Typical applications:**
- Coordinating robotic cells with conveyor systems and quality inspection stations
- Integrating edge gateways with modern MES and SCADA systems
- Building reconfigurable production lines for small-batch manufacturing
- Creating digital twins for production optimization and operator training
---
## License[](#license)
Areg SDK is released under the **[Apache License 2.0](LICENSE.txt)** - a permissive license suitable for both open-source and commercial use.
**Commercial support:** Enterprise licensing, training, and dedicated support available. Visit **[areg.tech](https://www.areg.tech/)** or email **info[at]areg[dot]tech**.
---
## Community and Contribution[](#community-and-contribution)
🚀 **Join the Areg SDK community** and help shape the future of service-oriented C++ development:
- 🛠️ [Contribute to open issues](https://github.com/aregtech/areg-sdk/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) - Review [contribution guidelines](CONTRIBUTING.md) first
- 💡 Share ideas or request features via [issues](https://github.com/aregtech/areg-sdk/issues) or [discussions](https://github.com/aregtech/areg-sdk/discussions)
- 🔀 Submit pull requests following [contribution guidelines](CONTRIBUTING.md)
- ⭐ **Give us a star** if you find Areg SDK useful - it helps others discover the project
- 🌍 **Showcase your project** - Building with Areg SDK? [Share your work](https://github.com/aregtech/areg-sdk/discussions/new?category=show-and-tell)!
**Add this badge to projects built with Areg SDK:**
```markdown
[](https://github.com/aregtech/areg-sdk)
```
---
## 3. Creating or Integrating Projects
You can create a new project or integrate Areg SDK into an existing one.
### Integration Options
| Method | Guide |
|--------|-------|
| CMake | [Integrating with CMake](./wiki/02b-cmake-integrate.md) |
| Visual Studio | [Integrating with Visual Studio](./wiki/02c-msvc-integrate.md) |
### Quick Start
Use the project setup tool to scaffold a new project:
```bash
# Linux/macOS
./tools/setup-project.sh
# Windows
tools\setup-project.bat
```
### Working Example
See the [Areg SDK Demo](https://github.com/aregtech/areg-sdk-demo) repository for a complete integrated project example.
---
## 4. Using Logging
Projects built with Areg SDK can include or exclude logging at compile time. When logging is enabled, individual log scopes and scope groups can be activated or deactivated at runtime.
### Logging Documentation
| Document | Description |
|----------|-------------|
| [Logging Configuration](./wiki/04a-logging-config.md) | Configure log output, levels, and scopes |
| [Developing with Logging](./wiki/04b-logging-develop.md) | Add logging to your application code |
| [Log Observer Application](./wiki/04c-logobserver.md) | Monitor logs in real time |
| [Log Collector Service](./wiki/04d-logcollector.md) | Aggregate logs from multiple processes |
### Quick Example
```cpp
#include "areg/trace/GETrace.h"
DEF_TRACE_SCOPE(myapp_main);
int main()
{
Application::initApplication();
TRACE_SCOPE(myapp_main);
TRACE_INFO("Application started");
// ... application code ...
return 0;
}
```
---
## 5. Using the Multitarget Router
The Multitarget Router (`mtrouter`) enables inter-process communication (IPC) between Areg-based applications. It can run as a standalone console application or as an operating system service.
### When You Need mtrouter
- Applications with **Public** services that communicate across processes
- Distributed systems with services on multiple devices
- Any multiprocess scenario using Areg IPC
### Configuration
All applications connecting to `mtrouter` need the [areg.init](../framework/areg/resources/areg.init) configuration file to specify connection settings.
### Documentation
See the [Multitarget Router Guide](./wiki/03a-mtrouter.md) for:
- Configuration options
- Running as a console application
- Installing as a system service (Linux, macOS, Windows)
- Network topology setup
---
================================================
FILE: docs/HelloService.md
================================================
# Hello Service Tutorial
```
This file is part of Areg SDK
Copyright (c) 2021-2026, Aregtech
Contact: info[at]areg.tech
Website: https://www.areg.tech
```
This tutorial demonstrates how to build multithreaded and multiprocess applications with Areg SDK using the same service and client components.
> [!NOTE]
> Complete source code is available in [examples/03_helloservice](../examples/03_helloservice/).
---
## Table of Contents
- [Introduction](#introduction)
- [What You Will Learn](#what-you-will-learn)
- [Key Concepts](#key-concepts)
- [Project Structure](#project-structure)
- [Service Interface Definition](#service-interface-definition)
- [Code Generation](#code-generation)
- [Understanding Models](#understanding-models)
- [Example Projects](#example-projects)
- [onethread](#onethread)
- [twothreads](#twothreads)
- [multiprocess](#multiprocess)
- [Running the Multiprocess Example](#running-the-multiprocess-example)
---
## Introduction
This example contains three projects under `examples/03_helloservice`. All three reuse the same **ServiceComponent** and **ClientComponent** implementations but demonstrate different execution models:
| Project | Description |
|---------|-------------|
| [onethread](../examples/03_helloservice/onethread/) | Service and client run in one thread |
| [twothreads](../examples/03_helloservice/twothreads/) | Service and client run in separate threads |
| [multiprocess](../examples/03_helloservice/multiprocess/) | Service and client run in separate processes |
---
## What You Will Learn
1. Define a model with service provider and consumer components
2. Load and unload models dynamically to control service lifecycle
3. Use automatic service discovery between components
4. Send requests from clients and receive responses from services
5. Build applications that scale from single-threaded to distributed
---
## Key Concepts
### Components and Services
- A **Component** can provide and/or consume multiple services
- Multiple providers of the same service can coexist, but each must have a unique **Role Name**
### Role Name Rules
| Service Type | Role Name Scope |
|--------------|-----------------|
| Local | Unique within the process |
| Public | Unique across the network |
### Connection Callbacks
Components receive notifications when connections change:
**Client Component:**
```cpp
void serviceConnected(NEService::eNetConnection status, ProxyBase& proxy)
```
**Service Component:**
```cpp
bool clientConnected(const ProxyAddress& client, NEService::eServiceConnection connectionStatus)
```
---
## Project Structure
```
03_helloservice/
├── services/ Service interface definition (.siml file)
├── generated/src/ Generated code from service interface
├── common/src/ Shared service and client implementations
├── onethread/ Single-thread example
├── twothreads/ Multi-thread example
└── multiprocess/ Multi-process example
├── serviceproc/ Service process
└── clientproc/ Client process
```
---
## Service Interface Definition
Create a service interface file that defines the communication contract. The file `services/HelloService.siml` defines a simple greeting service:
```xml
Hello world service exampleRequest to output a greeting.Name of the client requesting the greeting.Response indicating whether the greeting was successful.True if the greeting was output successfully.
```
**Key attributes:**
- `Category="Public"` makes the service accessible across processes (use `Category="Local"` for thread-only services)
- `MethodType="Request"` with `Response="HelloService"` links the request to its response
- `MethodType="Response"` defines what the service returns
---
## Code Generation
> [!NOTE]
> Requires [Java 17+](https://java.com/).
### Using CMake
In your `CMakeLists.txt`, use the `addServiceInterface` macro:
```cmake
addServiceInterface(03_generated examples/03_helloservice/services/HelloService.siml)
```
This creates a static library named `03_generated` containing the generated code.
### Using Command Line
```bash
java -jar /tools/codegen.jar \
--root= \
--doc=services/HelloService.siml \
--target=generated/src
```
### Generated Classes
| Class | Purpose |
|-------|---------|
| `HelloServiceStub` | Base class for service provider implementation |
| `HelloServiceClientBase` | Base class for service consumer implementation |
| `NEHelloService` | Namespace with service constants and types |
---
## Understanding Models
A **model** defines how threads, components, and services are organized. Models can be:
- **Static**: Declared at compile time using macros
- **Dynamic**: Created programmatically at runtime
### Model Lifecycle
1. `Application::loadModel()` starts threads and initializes components
2. Services become available and clients connect automatically
3. `Application::unloadModel()` stops threads and releases resources
### Static Model Macros
| Macro | Purpose |
|-------|---------|
| `BEGIN_MODEL` / `END_MODEL` | Define a model |
| `BEGIN_REGISTER_THREAD` / `END_REGISTER_THREAD` | Define a thread |
| `BEGIN_REGISTER_COMPONENT` / `END_REGISTER_COMPONENT` | Define a component |
| `REGISTER_IMPLEMENT_SERVICE` | Declare a service the component provides |
| `REGISTER_DEPENDENCY` | Declare a service the component consumes |
---
## Example Projects
### onethread
Both service and client run in the same thread. This is the simplest configuration.
```cpp
#include "areg/appbase/Application.hpp"
#include "areg/component/ComponentLoader.hpp"
#include "common/src/ServiceComponent.hpp"
#include "common/src/ClientComponent.hpp"
constexpr char const _model[]{ "ServiceModel" };
BEGIN_MODEL(_model)
BEGIN_REGISTER_THREAD("Thread1", NECommon::WATCHDOG_IGNORE)
BEGIN_REGISTER_COMPONENT("ServiceComponent", ServiceComponent)
REGISTER_IMPLEMENT_SERVICE(NEHelloService::ServiceName, NEHelloService::InterfaceVersion)
END_REGISTER_COMPONENT("ServiceComponent")
BEGIN_REGISTER_COMPONENT("ServiceClient", ClientComponent)
REGISTER_DEPENDENCY("ServiceComponent")
END_REGISTER_COMPONENT("ServiceClient")
END_REGISTER_THREAD("Thread1")
END_MODEL(_model)
int main()
{
Application::initApplication();
Application::loadModel(_model);
Application::waitAppQuit();
Application::unloadModel(_model);
Application::releaseApplication();
return 0;
}
```
---
### twothreads
Service and client run in separate threads within the same process.
```cpp
#include "areg/appbase/Application.hpp"
#include "areg/component/ComponentLoader.hpp"
#include "common/src/ServiceComponent.hpp"
#include "common/src/ClientComponent.hpp"
constexpr char const _model[]{ "ServiceModel" };
BEGIN_MODEL(_model)
BEGIN_REGISTER_THREAD("Thread1", NECommon::WATCHDOG_IGNORE)
BEGIN_REGISTER_COMPONENT("ServiceComponent", ServiceComponent)
REGISTER_IMPLEMENT_SERVICE(NEHelloService::ServiceName, NEHelloService::InterfaceVersion)
END_REGISTER_COMPONENT("ServiceComponent")
END_REGISTER_THREAD("Thread1")
BEGIN_REGISTER_THREAD("Thread2", NECommon::WATCHDOG_IGNORE)
BEGIN_REGISTER_COMPONENT("ServiceClient", ClientComponent)
REGISTER_DEPENDENCY("ServiceComponent")
END_REGISTER_COMPONENT("ServiceClient")
END_REGISTER_THREAD("Thread2")
END_MODEL(_model)
int main()
{
Application::initApplication();
Application::loadModel(_model);
Application::waitAppQuit();
Application::unloadModel(_model);
Application::releaseApplication();
return 0;
}
```
---
### multiprocess
Service and client run in separate processes, communicating through `mtrouter`.
**Service Process (`serviceproc`):**
```cpp
BEGIN_MODEL(_model)
BEGIN_REGISTER_THREAD("Thread1", NECommon::WATCHDOG_IGNORE)
BEGIN_REGISTER_COMPONENT("ServiceComponent", ServiceComponent)
REGISTER_IMPLEMENT_SERVICE(NEHelloService::ServiceName, NEHelloService::InterfaceVersion)
END_REGISTER_COMPONENT("ServiceComponent")
END_REGISTER_THREAD("Thread1")
END_MODEL(_model)
```
**Client Process (`clientproc`):**
```cpp
BEGIN_MODEL(_model)
BEGIN_REGISTER_THREAD("Thread1", NECommon::WATCHDOG_IGNORE)
BEGIN_REGISTER_COMPONENT("ServiceClient", ClientComponent)
REGISTER_DEPENDENCY("ServiceComponent")
END_REGISTER_COMPONENT("ServiceClient")
END_REGISTER_THREAD("Thread1")
END_MODEL(_model)
```
The same `ServiceComponent` and `ClientComponent` classes work without modification.
---
## Running the Multiprocess Example
1. **Start mtrouter**
The message router must be running for inter-process communication:
```bash
./mtrouter
```
2. **Start the service process**
Only one service instance should run:
```bash
./serviceproc
```
3. **Start client processes**
Multiple clients can connect simultaneously:
```bash
./clientproc
./clientproc # Additional clients get unique names automatically
```
4. **Observe the communication**
Clients discover the service, send greeting requests, and receive responses. The service processes requests from all connected clients.
> [!TIP]
> Configure the router address in [areg.init](../framework/areg/resources/areg.init) if running on different machines.
---
With this foundation, you can build scalable distributed applications where the same component code works across threads, processes, and network devices.
================================================
FILE: docs/HelloService.siml
================================================
Hello world service exampleRequest to output a greeting.Name of the client requesting the greeting.Response indicating whether the greeting was successful.True if the greeting was output successfully.
================================================
FILE: docs/POSIX.md
================================================
# POSIX API Reference
```
This file is part of Areg SDK
Copyright (c) Aregtech, 2021-2026
Contact: info[at]areg.tech
Website: https://www.areg.tech
```
This document describes POSIX API usage in Areg SDK for Linux and macOS platforms.
---
## Building with POSIX
To build with the POSIX API, define the preprocessor symbol **POSIX**. See the [Preprocessor Definitions](./wiki/02f-preprocessor-definitions.md) guide for details.
### Dependencies
Areg SDK uses POSIX.1c for multithreading and synchronization:
| Library | Purpose |
|---------|---------|
| `pthread` | Threading and synchronization |
| `ncurses` | Extended console features (optional) |
### Build Example
```bash
# Standard build
cmake -B ./build
cmake --build ./build
# Build with extended features (ncurses)
cmake -B ./build -DAREG_EXTENDED:BOOL=ON
cmake --build ./build
```
When `AREG_EXTENDED` is enabled, the build links against `ncurses` for enhanced console functionality.
---
## Platform-Specific Notes
### Linux
- Uses `pthread_setname_np` for thread naming (Linux-specific)
- Supports `timer_create`/`timer_settime` for high-resolution timers
- System services managed by systemd
### macOS
- Uses `dispatch_source` for timers instead of `timer_create`
- Thread naming via `pthread_setname_np` (macOS variant)
- System services managed by launchd
- Links against `libc++` (not `libstdc++`)
---
## POSIX API Functions Used
The following POSIX functions and macros are used in Areg SDK (including the Multitarget Router):
### File and Directory Operations
```
access chdir close fclose fopen fprintf
fsync ftruncate getcwd lseek mkdir mkdtemp
open opendir read readdir realpath rename
rmdir stat S_ISDIR unlink write
```
### Socket Operations
```
accept bind connect freeaddrinfo getaddrinfo
getpeername getsockopt htons inet_addr inet_ntoa
inet_ntop ioctl listen ntohs poll
recv select send setsockopt shutdown
socket
```
### Threading (pthread)
```
pthread_attr_destroy pthread_attr_init
pthread_attr_setdetachstate pthread_cancel
pthread_cond_destroy pthread_cond_init
pthread_cond_signal pthread_cond_timedwait
pthread_cond_wait pthread_condattr_destroy
pthread_condattr_init pthread_condattr_setpshared
pthread_create pthread_mutex_destroy
pthread_mutex_init pthread_mutex_lock
pthread_mutex_timedlock pthread_mutex_trylock
pthread_mutex_unlock pthread_mutexattr_destroy
pthread_mutexattr_init pthread_mutexattr_settype
pthread_self pthread_setcancelstate
pthread_setcanceltype pthread_setname_np
pthread_setschedparam pthread_spin_destroy
pthread_spin_init pthread_spin_lock
pthread_spin_trylock pthread_spin_unlock
```
### Time and Scheduling
```
ceil clock_gettime floor
gmtime gmtime_r localtime
localtime_r mktime nanosleep
sched_get_priority_max sched_get_priority_min
strftime timer_create timer_delete
timer_settime
```
### String and Memory
```
fflush fgets free getenv gets_s
isalnum printf snprintf sprintf strcpy
strlen strtod strtof strtol strtoll
strtoul strtoull swprintf va_end va_start
vsnprintf wcstof wcstol wcstoll wcstoul
wcstoull
```
### Process and User
```
execl getpid getpwuid signal
```
### ncurses (Extended Features)
```
cbreak clear delwin endwin getyx
mvwaddstr refresh vw_scanw waddstr wclrtoeol
wgetnstr wmove wrefresh
```
### File Descriptors
```
FD_ISSET FD_SET FD_ZERO
```
---
## Platform Requirements
Ensure your target platform supports all listed functions. Most modern Linux distributions and macOS versions include full support. For embedded or minimal systems, verify availability of:
- pthread library
- Socket support
- Timer functions (or use macOS dispatch alternatives)
================================================
FILE: docs/README.md
================================================
# Documentation Overview
```
This file is part of Areg SDK
Copyright (c) Aregtech, 2021-2026
Contact: info[at]areg.tech
Website: https://www.areg.tech
```
This document provides an overview of the Areg SDK file structure and documentation locations.
## File Structure
```
areg-sdk/ Root directory of Areg SDK
├── conf/ Build configuration files (CMake, MSBuild, MSVC)
├── docs/ Documentation files
│ ├── img/ Images and screenshots
│ ├── templates/ MSVC project templates
│ └── wiki/ Detailed wiki pages
├── examples/ Working examples demonstrating framework features
├── framework/ Source code
│ ├── areg/ Core communication engine library
│ ├── aregextend/ Extended features library (optional dependencies)
│ ├── areglogger/ Log observer library for receiving logs
│ ├── logcollector/ Log collection service (console or system service)
│ ├── logobserver/ Real-time log monitoring console application
│ └── mtrouter/ Multitarget Router for IPC (console or system service)
├── tests/ Unit tests
├── thirdparty/ External dependencies
├── tools/ Code generator and project scaffolding
├── LICENSE.txt License file
└── README.md Project overview
```
Classes in the `framework/areg` subdirectories are available for application development. However, classes in `private` subdirectories are internal and should not be used directly.
After building with CMake or MSBuild, compiled binaries are placed in the `product` subdirectory.
> [!TIP]
> Visit the [Areg SDK Wiki](./wiki/README.md) for detailed documentation. Contributions to improve the wiki are welcome.
## Documentation
| Document | Description |
|----------|-------------|
| [Developer Guide](./DEVELOP.md) | Technical guidance for developing distributed, service-enabled applications |
| [How-To Guide](./HOWTO.md) | Instructions for building, configuring, and integrating projects |
| [Use Cases](./USECASES.md) | Real-world scenarios demonstrating Areg SDK capabilities |
| [Service Interface](./ServiceInterface.md) | Service interface structure and XML format |
| [Hello Service Tutorial](./HelloService.md) | Step-by-step tutorial for creating your first service |
| [POSIX Reference](./POSIX.md) | POSIX API configuration and function list |
| [Win32 Reference](./WIN32.md) | Windows API configuration and function list |
| [Wiki](./wiki/README.md) | Comprehensive documentation and guides |
================================================
FILE: docs/Sample.siml
================================================
This is an example of defining service interface.Some structure with data. It will become new type.0Some filed 10Just another field""More field.falseDateTime::getNow()-10This example exports NEMemory::uAlign in the service interface.NEMemoryareg/base/NEMemory.hppDefines new type of arrayArrayuint32New type of linked list.LinkedListStringThis example defines hash-map where key is exported and value is new data type.HashMapSomeStructStringAn attribute to notify subscribers only when value is changed.Another attribute to notify subscribers any time when value is set (maybe not changed).This is an Attribute that mark as deprecatedExample to deprecate data.Request and response with no parameters.A request with parameters that is connected to SomeResponse interface.SomeEnum::Nothingparameter with default valueResponse, where 2 requests can connect.Another request with parameter that is connected with SomeResponse methodA request with no response.Broadcast with parameters. Can pass multiple parameters at once.We already have 'param1' in response, this parameter name must differ.This request does not have a response.This broadcast has not parameters.100define a constant if need."This is a constant"A constant, which is a string.falseThis is a constant, which we mark as deprecated.Deprecate sample.can make additional includesSupposed to have a new DataType XML file that can be included in the multiple Service Interface.
================================================
FILE: docs/Sample.xsd
================================================
================================================
FILE: docs/ServiceInterface.md
================================================
# Service Interface Guide
```
This file is part of Areg SDK
Copyright (c) 2021-2026, Aregtech
Contact: info[at]areg.tech
Website: https://www.areg.tech
```
This guide explains how to define service interfaces and generate code for Areg SDK applications.
---
## Table of Contents
- [Overview](#overview)
- [Service Interface Structure](#service-interface-structure)
- [Overview Section](#overview-section)
- [Data Types](#data-types)
- [Attributes](#attributes)
- [Methods](#methods)
- [Constants](#constants)
- [Includes](#includes)
- [Code Generator](#code-generator)
- [Generated Code](#generated-code)
- [Benefits](#benefits)
---
## Overview
A **Service Interface** defines the communication contract between service providers and consumers in Areg SDK. It specifies:
- Service identity (name, version, scope)
- Custom data types (structures, enumerations, containers)
- Attributes (observable data)
- Methods (requests, responses, broadcasts)
- Constants
Service interfaces are defined in XML files (`.siml` extension). The code generator reads these files and creates C++ base classes that handle serialization, message routing, and communication.
See [Sample.siml](./Sample.siml) for a complete example.
---
## Service Interface Structure
### Overview Section
The `` element defines service identity:
```xml
Example service interface.
```
| Attribute | Description |
|-----------|-------------|
| `Name` | Service name (used in generated namespace) |
| `Version` | Service version for compatibility checking |
| `Category` | `Public` for IPC, `Local` for single-process only |
**Category values:**
- `Public` (or `isRemote="true"`) — Accessible across processes and network
- `Local` (or `isRemote="false"`) — Only accessible within the same process
---
### Data Types
The `` section defines custom types. All types must be serializable.
#### Structures
```xml
0Field 1Field 2
```
#### Enumerations
```xml
-1Invalid enum value0
```
#### Imported Types
Reference types from external headers:
```xml
NEMemoryareg/base/NEMemory.hpp
```
#### Containers
Define arrays, lists, or maps:
**Array:**
```xml
Arrayuint32
```
**Hash Map:**
```xml
HashMapSomeStructString
```
| Container Type | Description |
|----------------|-------------|
| `Array` | Dynamic array |
| `LinkedList` | Doubly-linked list |
| `HashMap` | Key-value map (requires `BaseTypeKey`) |
---
### Attributes
Attributes are observable data that clients can subscribe to. When an attribute changes, subscribed clients receive notifications.
```xml
Notifies subscribers when the value changes.
```
| Notify Value | Behavior |
|--------------|----------|
| `OnChange` | Notify only when value changes |
| `Always` | Notify on every update |
---
### Methods
Methods define the service API. There are three types:
#### Requests
Client-initiated calls to the service:
```xml
Request that expects a response.
```
- `Response` attribute links to the response method
- Omit `Response` for one-way requests
#### Responses
Service replies to requests:
```xml
```
Responses are sent only to the requesting client.
#### Broadcasts
Service-initiated notifications to all subscribed clients:
```xml
```
Clients must explicitly subscribe to receive broadcasts.
---
### Constants
Shared read-only values:
```xml
100
```
Constants are accessible from both providers and consumers.
---
### Includes
Additional header files required by the service:
```xml
```
---
## Code Generator
The code generator creates C++ classes from service interface files.
### Requirements
- Java 17 or later
### Usage
```bash
java -jar /tools/codegen.jar \
--root= \
--doc= \
--target=
```
| Parameter | Description |
|-----------|-------------|
| `--root` | Project root directory |
| `--doc` | Path to `.siml` file (relative to root) |
| `--target` | Output directory for generated files |
### CMake Integration
Use the `addServiceInterface` macro:
```cmake
addServiceInterface(MyService_generated services/MyService.siml)
```
This creates a static library containing the generated code.
For details, see the [Code Generator Guide](./wiki/03a-code-generator.md).
---
## Generated Code
The generator creates:
| File | Purpose |
|------|---------|
| `NE.hpp` | Namespace with types, constants, and method IDs |
| `Stub.hpp` | Base class for service provider |
| `ClientBase.hpp` | Base class for service consumer |
| `Events.hpp` | Event classes for request/response handling |
| `Proxy.hpp` | Proxy class for client-side communication |
### Implementing a Service Provider
Extend the generated `Stub` class and implement request handlers:
```cpp
class MyServiceImpl : public MyServiceStub
{
public:
void requestSomeRequest(/* parameters */) override
{
// Implement business logic
responseSomeResponse(true);
}
};
```
### Implementing a Service Consumer
Extend the generated `ClientBase` class and handle responses:
```cpp
class MyClient : public MyServiceClientBase
{
public:
void responseSomeResponse(bool succeeded) override
{
// Handle response
}
};
```
---
## Benefits
| Benefit | Description |
|---------|-------------|
| **Consistency** | Uniform API definitions across services |
| **Automation** | Generated code handles serialization and routing |
| **Type Safety** | Compile-time checking of method signatures |
| **Flexibility** | Same interface works for Local and Public services |
| **Maintainability** | Single source of truth for service contracts |
================================================
FILE: docs/USECASES.md
================================================
# Use Cases and Benefits
The Areg communication engine supports a wide range of multithreaded and multiprocess applications. This document presents practical examples of how to use the framework for building intelligent connected devices.
## Table of Contents
- [Distributed Solutions](#distributed-solutions)
- [Driverless Devices](#driverless-devices)
- [Real-Time Solutions](#real-time-solutions)
- [Digital Twins](#digital-twins)
- [Simulation and Testing](#simulation-and-testing)
---
## Distributed Solutions
Click to show / hide
Areg is a distributed services solution where components interact across network nodes as if they were in a single process. Developers define runtime-loadable models to establish service relationships and distribution.
### Example: Two Processes with Connected Services
Consider two processes: one provides a service, the other both consumes and provides services.
**Process A: Service Provider (`service.cpp`)**
```cpp
// service.cpp - defines a service provider
BEGIN_MODEL("MyModel")
BEGIN_REGISTER_THREAD("Thread1")
BEGIN_REGISTER_COMPONENT("SystemShutdown", SystemShutdownService)
REGISTER_IMPLEMENT_SERVICE(NESystemShutdown::ServiceName, NESystemShutdown::InterfaceVersion)
END_REGISTER_COMPONENT("SystemShutdown")
END_REGISTER_THREAD("Thread1")
END_MODEL("MyModel")
```
**Process B: Service Consumer and Provider (`mixed.cpp`)**
```cpp
// mixed.cpp - defines a service that also consumes another service
BEGIN_MODEL("MyModel")
BEGIN_REGISTER_THREAD("Thread1")
BEGIN_REGISTER_COMPONENT("RemoteRegistry", RemoteRegistryService)
REGISTER_IMPLEMENT_SERVICE(NERemoteRegistry::ServiceName, NERemoteRegistry::InterfaceVersion)
REGISTER_DEPENDENCY("SystemShutdown")
END_REGISTER_COMPONENT("RemoteRegistry")
END_REGISTER_THREAD("Thread1")
END_MODEL("MyModel")
```
**Common Main Function**
Both processes use the same entry point structure:
```cpp
int main()
{
Application::initApplication(); // Initialize defaults
Application::loadModel("MyModel"); // Load model, start services
Application::waitAppQuit(); // Wait for quit signal
Application::unloadModel("MyModel");// Unload model, stop services
Application::releaseApplication(); // Release resources
return 0;
}
```
### How It Works
1. **service.cpp** registers `SystemShutdown`, which implements the `NESystemShutdown` interface
2. **mixed.cpp** registers `RemoteRegistry`, which implements `NERemoteRegistry` and depends on `SystemShutdown`
3. When both processes start, services discover each other automatically through `mtrouter`
4. Developers implement business logic in `SystemShutdownService` and `RemoteRegistryService` classes
This approach makes it easy to build multiprocess applications where services can be distributed and accessed remotely within the network.
See the [Hello Service Tutorial](./HelloService.md) for a complete example, and browse the [examples](../examples/) directory for more multithreading and multiprocessing samples.
---
## Driverless Devices
Click to show / hide
Traditional devices require kernel-mode drivers installed on the host system:
Areg enables a driverless approach where devices expose services instead of requiring driver installation:
### Benefits
- **Faster development**: Services are easier to develop than kernel-mode drivers
- **Lower risk**: User-mode code is safer and simpler to debug
- **Automated client generation**: The code generator creates client objects from service interface definitions
- **No special techniques required**: Develop services like standard user-mode applications
---
## Real-Time Solutions
Click to show / hide
Areg automatically generates and delivers messages to targets, invoking specific object methods in real time with minimal network latency. This makes it suitable for time-sensitive applications in:
- Automotive systems
- Drone fleet coordination
- Medical technology
- Manufacturing monitoring
- Real-time process control
---
## Digital Twins
Click to show / hide
Areg's event-driven, service-oriented architecture combined with real-time communication provides a foundation for digital twin applications:
- **Visualization**: Monitor external device states in real time
- **Control**: Send commands to physical devices through their digital representations
- **Immediate reaction**: Respond instantly to environment or device state changes
- **Direct communication**: No additional middleware layers required
This approach is well-suited for emergency response, security systems, and safety-critical applications where immediate state synchronization is essential.
---
## Simulation and Testing
Click to show / hide
Software simulation is valuable when hardware is unavailable or impractical for testing. Simulated environments are:
- Portable and accessible
- Useful for optimizing solutions without hardware risks
- Suitable for remote development and outsourcing
### Testing with Simulated Services
Areg's distributed architecture simplifies testing in simulated environments. A simulation application can provide identical Data layer services, allowing seamless testing of application logic without physical hardware.
This technique also enables API-driven test automation, where simulated services respond to client requests predictably for automated verification.
---
================================================
FILE: docs/WIN32.md
================================================
# Win32 API Reference
```
This file is part of Areg SDK
Copyright (c) Aregtech, 2017-2026
Contact: info[at]areg.tech
Website: https://www.areg.tech
```
This document describes Win32 API usage in Areg SDK for Windows platforms.
---
## Building with Win32
To build with the Win32 API, define the preprocessor symbol **WINDOWS**. See the [Preprocessor Definitions](./wiki/02f-preprocessor-definitions.md) guide for details.
### Build Options
| Method | Guide |
|--------|-------|
| CMake | [Building with CMake](./wiki/01b-cmake-build.md) |
| MSBuild | [Building with Visual Studio](./wiki/01c-msvc-build.md) |
### Dependencies
Areg SDK uses Windows Sockets and Win32 API for:
- Networking
- Multithreading
- Synchronization
When `AREG_EXTENDED` is enabled, extended console features require Windows 2000 or later.
### Build Example
```batch
:: Standard build
msbuild /m /property:Configuration=Release /property:Platform=x64 ./areg-sdk.sln
:: Build with extended features
msbuild /m /property:Configuration=Debug /property:Platform=x64 /property:AregExtended=1 ./areg-sdk.sln
```
---
## Platform Requirements
| Feature | Minimum Windows Version |
|---------|------------------------|
| Standard build | Windows XP |
| Extended features | Windows 2000 |
| Service support | Windows XP |
---
## Win32 API Functions Used
The following Win32 API functions are used in Areg SDK (including the Multitarget Router):
### Threading and Synchronization
```
CreateThread ExitThread GetCurrentThreadId
SetThreadPriority SuspendThread ResumeThread
TerminateThread TlsAlloc TlsFree
TlsGetValue TlsSetValue Sleep
SleepEx WaitForSingleObject WaitForMultipleObjects
CreateEvent SetEvent ResetEvent
CloseHandle CreateMutex ReleaseMutex
InitializeCriticalSection DeleteCriticalSection
EnterCriticalSection LeaveCriticalSection
TryEnterCriticalSection InitializeConditionVariable
SleepConditionVariableCS WakeConditionVariable
WakeAllConditionVariable
```
### Socket Operations (Winsock2)
```
WSAStartup WSACleanup WSAGetLastError
socket bind listen
accept connect send
recv closesocket shutdown
setsockopt getsockopt select
getaddrinfo freeaddrinfo inet_ntop
htons ntohs ioctlsocket
```
### File and Directory Operations
```
CreateFile ReadFile WriteFile
CloseHandle GetFileSize SetFilePointer
CreateDirectory RemoveDirectory DeleteFile
GetCurrentDirectory SetCurrentDirectory FindFirstFile
FindNextFile FindClose GetFileAttributes
GetTempPath GetTempFileName
```
### Time Functions
```
GetSystemTime GetLocalTime SystemTimeToFileTime
FileTimeToSystemTime GetTickCount GetTickCount64
QueryPerformanceCounter QueryPerformanceFrequency
CreateWaitableTimer SetWaitableTimer
CancelWaitableTimer
```
### Process and Module
```
GetCurrentProcess GetCurrentProcessId GetModuleFileName
GetModuleHandle GetCommandLine GetEnvironmentVariable
```
### Memory
```
HeapAlloc HeapFree HeapReAlloc
VirtualAlloc VirtualFree GetProcessHeap
```
### Console (Extended Features)
```
GetStdHandle SetConsoleCursorPosition
GetConsoleScreenBufferInfo SetConsoleTextAttribute
WriteConsole ReadConsole SetConsoleMode
GetConsoleMode
```
### Service Control
```
RegisterServiceCtrlHandler SetServiceStatus
StartServiceCtrlDispatcher OpenSCManager
CreateService DeleteService OpenService
StartService ControlService CloseServiceHandle
```
### String Operations
```
MultiByteToWideChar WideCharToMultiByte lstrcpy
lstrlen wsprintf wvsprintf
```
---
## Notes
- Winsock2 must be initialized with `WSAStartup` before socket operations
- Service functions are used only when running as a Windows service
- Console functions are used only with `AREG_EXTENDED` enabled
================================================
FILE: docs/templates/Readme.md
================================================
# Templates
This folder contains the temaplates that developer may use to create projects using prefered IDE. Regardless by using `cmake` it is possible to generate appropriate project files for prefered IDEs, sometimes it is more useful to create them manually.
1. `msvc-static-lib.vcxproj` and `msvc-static-lib.vcxproj.filter` files -- use these files to compile static library (for example, generated codes) under Microsoft Visual Studio.
2. `msvc-exe.vcxproj` and `msvc-exe.vcxproj.filter` files -- use these files to compile executables with Microsoft Visual Studio, which is linked (importing) with `areg` library. Pay attnetion on importing preprocessor define wheather the application is compiled with static or shared library.
3. `eclipse-areg.project` and `eclipse-areg.cproject` files -- use these files to compile `areg` library under `Eclipse`.
* Copy file `eclipse-areg.project` to `framework/areg` folder and rename it to `.project`.
* Copy file `eclipse-areg.cpproject` to `framework/areg` folder and rename it to `.cpproject`.
* Open `Eclipse` IDE with the workspace in `areg-sdk` folder and import `areg` project.
* Compile the project either as a static lbirary or shared (required additional changes in the project settings).
4. `eclipse-mtrouter.cproject` and `eclipse-mtrouter.project` files -- use these files to compile `mtrouter` service linked with `areg` library.
* Copy file `eclipse-mtrouter.project` to `framework/mtrouter`folder and rename to `.project`.
* Copy file `eclipse-mtrouter.cproject` to `framework/mtrouter`folder and rename to `.cproject`.
* Open `Eclipse` IDE with the workspace in `areg-sdk` folder and import `mtrouter` project.
* Compile the project linked with the `areg` library and other dependent libraries.
5. `eclipse-static.cproject` and `eclipse-static.project` files -- use these files to compile projects as static libraries (for example, generated codes).
* Copy `eclipse-static.project` to the folder, which sources should be compiled as static libraries, and rename as `.project`.
* Copy `eclipse-static.cproject` to the same folder and rename as `.cproject`.
* Open the files and replace all `replace-me-static` with the name of folder / project.
* Open `Eclipse` IDE and import projects.
* Compile the projects.
6. `eclipse-executable.cproject` and `eclipse-executable.project` files -- use these files to create executable, which is linked with `areg` and (optional) other libraries (forexample, static library of generated codes).
* Copy `eclipse-executable.project` into the folder, which sources should be compiled as executable, and rename as `.project`.
* Replace all `replace-me-executable` with the name of the project.
* If the executable is linked with other library (static), replace `replace-me-static` with the name of library to link.
* Copy `eclipse-executable.cproject` into the same folder and rename as `.cproject`
* Replace all `replace-me-static` with the (optional) name of static library to link.
* Replace all `replace-me-executable` with the name of executable.
* Open `Eclipse` IDE and import the projects.
* Make sure all symbols are imported and incluse folders are set properly.
* Copile the projects.
================================================
FILE: docs/templates/contributors.yml
================================================
name: Generate Contributors
on:
schedule:
- cron: '0 1 * * 0' # At 01:00 on Sunday.
push:
branches:
- master
jobs:
contributors:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Create contributors
uses: wow-actions/contributors-list@v1.2.0
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
truncate: 0
userNameHeight: 12
includeBots: false
affiliation: all
excludeUsers: gitter-badger
count: 18
noCommit: true
svgPath: '${{github.workspace}}/docs/img/contributors.svg'
itemTemplate: >
{{{ name }}}
- name: Create a PR
uses: peter-evans/create-pull-request@v5
with:
commit-message: Update Contributors
title: "[automated] Update Contributors File"
token: ${{ secrets.GITHUB_TOKEN }}
labels: automated-pr
assignees: aregtech
reviewers: aregtech
draft: false
================================================
FILE: docs/templates/msvc-dynamic-lib.vcxproj
================================================
{4056956C-7E12-4432-86F8-D900A52866A4}replace-mereplace-meWin32ProjDynamicLibrary$(OutLibDir)IMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)ConsoletruetrueIMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)Console
================================================
FILE: docs/templates/msvc-dynamic-lib.vcxproj.filters
================================================
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}cpp;c;cc;cxx;def;odl;idl;hpj;asm;asmx{93995380-89BD-4b04-88EB-625FBE52EBFB}h;hpp;hxx;hm;inl;inc;xsd;siml{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}bat;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;txt
================================================
FILE: docs/templates/msvc-exe.vcxproj
================================================
{8273239C-C5A8-4752-9DFC-E1678222C36E}replace-mereplace-meWin32ProjApplicationIMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)ConsoletruetrueIMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)Console
================================================
FILE: docs/templates/msvc-exe.vcxproj.filters
================================================
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}cpp;c;cc;cxx;def;odl;idl;hpj;asm;asmx{93995380-89BD-4b04-88EB-625FBE52EBFB}h;hpp;hxx;hm;inl;inc;xsd;siml{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}bat;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;txt
================================================
FILE: docs/templates/msvc-static-lib.vcxproj
================================================
{4056956C-7E12-4432-86F8-D900A52866A4}replace-mereplace-meWin32ProjStaticLibrary$(OutLibDir)IMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)ConsoletruetrueIMPORT_SHARED_SYMBOLS;%(PreprocessorDefinitions)Console
================================================
FILE: docs/templates/msvc-static-lib.vcxproj.filters
================================================
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}cpp;c;cc;cxx;def;odl;idl;hpj;asm;asmx{93995380-89BD-4b04-88EB-625FBE52EBFB}h;hpp;hxx;hm;inl;inc;xsd;siml{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}bat;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;txt
================================================
FILE: docs/wiki/01a-areg-package.md
================================================
# Installing Areg SDK with vcpkg Package Manager
This guide covers installing vcpkg, setting up the Areg SDK package, and creating projects with CMake or Visual Studio.
---
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Why Use vcpkg](#why-use-vcpkg)
3. [Install vcpkg](#install-vcpkg)
4. [Install Areg SDK Package](#install-areg-sdk-package)
5. [Create a CMake Project](#create-a-cmake-project)
6. [Create a Visual Studio Project](#create-a-visual-studio-project)
7. [Troubleshooting](#troubleshooting)
---
## Prerequisites
Before installing Areg SDK via vcpkg, ensure you have:
- **CMake 3.20+** - Build system generator
- **Git** - Version control (required by vcpkg)
- **C++17 Compiler** - GCC, Clang/LLVM, or MSVC
- **Java 17+** - Required for Areg code generation tools
**Supported Platforms:** Windows, Linux, macOS
**Supported Architectures:** x86, x86_64, ARM, AArch64
---
## Why Use vcpkg
[vcpkg](https://github.com/microsoft/vcpkg) is Microsoft's cross-platform C++ package manager that simplifies dependency management:
✅ **Cross-platform** - Works on Windows, Linux, and macOS
✅ **CMake integration** - Automatic library detection
✅ **Visual Studio integration** - Zero-configuration package usage
✅ **Reproducible builds** - Consistent library versions across teams
**Alternative installation methods:** See [CMake FetchContent Integration](./02b-cmake-integrate.md) for direct source integration.
---
## Install vcpkg
### Step 1: Clone vcpkg Repository
Open your terminal (Command Prompt, PowerShell, or Bash) and run:
```bash
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
```
### Step 2: Bootstrap vcpkg
Build the vcpkg executable:
**Windows:**
```powershell
.\bootstrap-vcpkg.bat
```
**Linux/macOS:**
```bash
./bootstrap-vcpkg.sh
```
### Step 3: Add vcpkg to PATH (Optional)
For convenient access from any directory, add vcpkg to your system PATH.
**Windows (PowerShell):**
```powershell
$env:PATH += ";"
```
**Linux/macOS:**
```bash
export PATH=$PATH:
```
Replace `` with the actual vcpkg installation path.
> [!TIP]
> Add the PATH export to your shell configuration file (~/.bashrc, ~/.zshrc, or PowerShell profile) for persistence.
### Step 4: Integrate with Build Tools
For seamless Visual Studio integration, run:
```bash
vcpkg integrate install
```
**This command:**
- Configures Visual Studio to auto-detect vcpkg packages
- Displays the CMake toolchain file path (save this for CMake projects)
- Requires administrator/sudo privileges on some systems
**Example output:**
```
Applied user-wide integration for this vcpkg root.
All MSBuild C++ projects can now #include any installed libraries.
Linking will be handled automatically.
Installing new libraries will make them instantly available.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
```
---
## Troubleshooting
### vcpkg Command Not Found
**Problem:** Terminal doesn't recognize `vcpkg` command.
**Solution:** Either navigate to vcpkg directory or add it to PATH:
```bash
cd
./vcpkg install areg
```
Or add vcpkg to PATH as described in [Step 3](#step-3-add-vcpkg-to-path-optional).
### CMake Cannot Find areg Package
**Problem:** CMake reports `Could not find a package configuration file provided by "areg"`.
**Solution:** Ensure CMAKE_TOOLCHAIN_FILE points to vcpkg:
```bash
cmake -B ./build -DCMAKE_TOOLCHAIN_FILE="/scripts/buildsystems/vcpkg.cmake"
```
Get the exact path from `vcpkg integrate install` output.
### Visual Studio Cannot Find Areg Headers
**Problem:** IntelliSense shows errors for `#include "areg/base/String.hpp"`.
**Solution:**
1. Verify `vcpkg integrate install` was executed
2. Restart Visual Studio
3. Check vcpkg integration status:
```bash
vcpkg integrate install
```
4. If issues persist, remove and re-add integration:
```bash
vcpkg integrate remove
vcpkg integrate install
```
### Wrong Architecture or Platform
**Problem:** Build fails with architecture mismatch errors.
**Solution:** Specify triplet explicitly when installing:
**For 64-bit Windows:**
```bash
vcpkg install areg:x64-windows
```
**For 64-bit Linux:**
```bash
vcpkg install areg:x64-linux
```
**For macOS:**
```bash
vcpkg install areg:x64-osx
```
### Java Not Found During Installation
**Problem:** vcpkg reports Java is required but not found.
**Solution:** Install Java 17+ and ensure it's in PATH:
```bash
java -version
```
Should output Java version 17 or higher. If not, install from [Adoptium](https://adoptium.net/) or your system package manager.
---
## Additional Resources
**Build Guides:**
- [CMake Configuration Options](./02d-cmake-config.md) - Complete configuration reference
- [CMake Integration Guide](./02b-cmake-integrate.md) - Using Areg SDK in your projects
- [vcpkg Installation](./02d-cmake-vcpkg.md) - Alternative installation method
**Troubleshooting:**
- [Linux Build Troubleshooting](./07b-troubleshooting-cmake-linux-builds.md)
- [Integration Troubleshooting](./07c-troubleshooting-integration.md)
**Help:**
If you encounter issues not covered here, open a [discussion](https://github.com/aregtech/areg-sdk/discussions) or [issue](https://github.com/aregtech/areg-sdk/issues) on GitHub.
---
## Running Applications
### Step 1: Navigate to Areg SDK Directory
```bash
cd ~/projects/areg-sdk
```
Or if using Windows clone:
```bash
cd /mnt/c/projects/areg-sdk
```
### Step 2: Run Example Application
**Run the minimal RPC example:**
```bash
./product/build/gnu-g++/linux-64-x86_64-release-shared/bin/01_minimalrpc
```
**Expected output:**
```
'Hello Service!'
Exiting application ...
```
**Run the local service example:**
```bash
./product/build/gnu-g++/linux-64-x86_64-release-shared/bin/10_locservice
```
**Expected output:**
```
A Demo to demonstrate simple request, response, and broadcast ...
"Hello client [ TestServiceClient ]!", remaining [ 36 ] to process.
...
Exit application; check logs for details.
```
> [!NOTE]
> For complete list of examples and detailed instructions, see [Examples README](../../examples/README.md).
---
## Interactive Setup
The tool asks three questions with sensible defaults.
### Prompt 1: Project Name
```
Specify the name of your new project [default: areg_hello]:
```
**Options:**
- Press **Enter** - Use default name (`areg_hello`)
- Type name - Use custom name (e.g., `my_service_app`)
**Example:**
```
Specify the name of your new project [default: areg_hello]: my_messenger
```
**Used for:**
- Directory name (if root not specified)
- CMake project name
- Executable name(s)
### Prompt 2: Root Directory
```
Specify the root directory of your new project [default: ./areg_hello]:
```
**Options:**
- Press **Enter** - Use `./[project_name]`
- Type path - Use custom location (e.g., `~/projects/my_app`)
**Example:**
```
Specify the root directory of your new project [default: ./my_messenger]: ~/dev/my_messenger
```
**Notes:**
- Directory created if it doesn't exist
- Relative or absolute paths supported
- Parent directory must exist
### Prompt 3: Project Mode
```
Choose mode - (1) 'multiprocessing' or (2) 'multithreading' [default: 1]:
```
**Options:**
- **1** or **Enter** - Multiprocessing (two executables)
- **2** - Multithreading (single executable)
**Example:**
```
Choose mode - (1) 'multiprocessing' or (2) 'multithreading' [default: 1]: 2
```
**See:** [Project Modes](#project-modes) for detailed comparison.
### Complete Example Session
```bash
$ ./areg-sdk/tools/project-setup.sh
Specify the name of your new project [default: areg_hello]: chat_service
Specify the root directory of your new project [default: ./chat_service]:
Choose mode - (1) 'multiprocessing' or (2) 'multithreading' [default: 1]: 2
Areg 2 project created at: ./chat_service
Build instructions:
cd chat_service
cmake -B ./build
cmake --build ./build
```
---
## Building and Running
### Building Multithreading Project
**Step 1: Navigate to project**
```bash
cd areg_hello
```
**Step 2: Configure build**
```bash
cmake -B ./build
```
**Expected output (first time):**
```
-- The C compiler identification is GNU 11.4.0
-- The CXX compiler identification is GNU 11.4.0
-- >>> Fetched Areg SDK from GitHub to /path/to/build/packages
-- >>> Location of 'areg.cmake' /path/to/build/packages/areg-src/areg.cmake
-- Configuring done
-- Generating done
-- Build files written to: /path/to/areg_hello/build
```
**Time:** 10-60 seconds (first time), 1-2 seconds (subsequent)
**Step 3: Build**
```bash
cmake --build ./build -j20
```
**Expected output:**
```
[ 5%] Generating gen_areg_hello
[ 10%] Building CXX object src/CMakeFiles/areg_hello.dir/main.cpp.o
[ 95%] Linking CXX executable areg_hello
[100%] Built target areg_hello
```
**Time:** 3-8 minutes (first time with Areg SDK), 2-5 seconds (rebuild)
**Step 4: Run**
```bash
./build/bin/areg_hello
```
**Expected output:**
```
'Hello Service!'
Received response, end application
```
---
### Building Multiprocessing Project
**Build (same as multithreading):**
```bash
cd areg_hello
cmake -B ./build
cmake --build ./build -j20
```
**Executables created:**
- `./build/bin/areg_hello_provider`
- `./build/bin/areg_hello_consumer`
**Step 1: Start provider (Terminal 1)**
```bash
./build/bin/areg_hello_provider
```
**Step 2: Start consumer (Terminal 2)**
```bash
./build/bin/areg_hello_consumer
```
**Expected output:**
**Terminal 1 (provider):**
```
'Hello Service!'
(Process exits)
```
**Terminal 2 (consumer):**
```
'Good bye Service!'
(Process exits)
```
> [!IMPORTANT]
> For inter-process communication, both processes must be on the same machine or `mtrouter` must be configured for network communication.
---
### Message Router Setup
For **multiprocessing** projects, `mtrouter` is required for inter-process communication (IPC).
**Starting mtrouter:**
```bash
# From Areg SDK or areg_hello build
./build/bin/mtrouter
```
Without `mtrouter`, multiprocessing applications will run as isolated multithreading applications - internal services work within each process, but public services cannot communicate across processes. For network communication across machines, configure mtrouter address in your application's configuration file. See [Areg SDK Multitarget Router (mtrouter)](./03a-mtrouter.md) for details.
> [!NOTE]
> Multithreading projects do not need `mtrouter` - all communication is in-process.
---
## Prerequisites
### Required Tools
- **Visual Studio 2019+** with C++ desktop development workload
- **Git** - Version control
- **Java 17+** - For code generation tools (if using ORPC services)
### Verify Installation
**Visual Studio:**
- Launch Visual Studio
- Check version: **Help → About Microsoft Visual Studio**
- Should show version 16.0 (VS 2019) or higher
**Git:**
```powershell
git --version
```
**Java (if using code generation):**
```powershell
java -version
```
Should output version 17 or higher.
---
## Detailed Option Descriptions
### 1. AREG_COMPILER_FAMILY
**Description:** Select compiler family for C++ and C sources.
**Possible Values:**
- `gnu` - GCC compiler family (`g++`, `gcc`)
- `llvm` - LLVM/Clang compiler family (`clang++`, `clang`)
- `msvc` - Microsoft Visual C++ (`cl`)
- `cygwin` - GCC for Cygwin on Windows
**Default:** `gnu` on Linux/Cygwin, `msvc` on Windows
**Example:**
```bash
cmake -B ./build -DAREG_COMPILER_FAMILY=llvm
```
> [!NOTE]
> This option is ignored if `CMAKE_CXX_COMPILER` is set and `user.cmake` is included after the first `project()` call.
---
### 2. AREG_COMPILER
**Description:** Specify exact compiler executable by name or full path.
**Possible Values:** `g++`, `gcc`, `clang++`, `clang`, `c++`, `cc`, `cl`, `clang-cl`, or full path
**Default:** System default compiler
**Example:**
```bash
cmake -B ./build -DAREG_COMPILER=/usr/bin/clang++-14
```
> [!NOTE]
> Setting `CMAKE_CXX_COMPILER` directly achieves the same effect. If `CMAKE_CXX_COMPILER` is set and `user.cmake` is included after `project()`, this option is ignored.
---
### 7. AREG_BUILD_TYPE
**Description:** Build configuration type, equivalent to `CMAKE_BUILD_TYPE`.
**Possible Values:**
- `Release` - Optimized build, no debug symbols
- `Debug` - Debug symbols, no optimization
**Default:** `Release`
**Example:**
```bash
cmake -B ./build -DAREG_BUILD_TYPE=Debug
```
> [!NOTE]
> If `CMAKE_BUILD_TYPE` is set and `user.cmake` is included after `project()`, this option is ignored and `CMAKE_BUILD_TYPE` takes precedence.
---
### 9. AREG_BUILD_EXAMPLES
**Description:** Enable or disable building example applications.
**Possible Values:** `ON`, `OFF`
**Default:** `ON`
**Dependencies:** Some examples require MFC (Microsoft Foundation Classes) on Windows
**Example:**
```bash
cmake -B ./build -DAREG_BUILD_EXAMPLES=OFF
```
---
### 14. AREG_GTEST_PACKAGE
**Description:** Use system-installed Google Test package.
**Possible Values:** `ON`, `OFF`
**Default:** `ON`
**Example:**
```bash
cmake -B ./build -DAREG_GTEST_PACKAGE=OFF
```
**Behavior:**
- `ON` - Try system package first, fetch from Google repository if not found
- `OFF` - Always fetch from Google repository
---
### 16. AREG_BUILD_ROOT
**Description:** Main directory for all build artifacts, third-party dependencies, and generated code.
**Default:** `/product`
**Example:**
```bash
cmake -B ./build -DAREG_BUILD_ROOT=/tmp/areg-build
```
**Note:** This directory and its contents can be safely deleted without affecting source code.
---
## CMake Macros
### macro_check_fix_areg_cxx_standard
**Syntax:** `macro_check_fix_areg_cxx_standard()`
**Purpose:** Validates and sets C++ standard compatibility.
**Details:** Ensures `CMAKE_CXX_STANDARD` matches `AREG_CXX_STANDARD`. Outputs warning if incompatible. Variable `AREG_CXX_STANDARD` must be defined before calling this macro.
**Usage:**
```cmake
macro_check_fix_areg_cxx_standard()
```
---
### macro_normalize_path
**Syntax:** `macro_normalize_path(normal_path os_path)`
**Purpose:** Normalizes Windows paths to Cygwin format if applicable.
**Parameters:**
- `normal_path` [out] - Variable to hold normalized path
- `os_path` [in] - Windows-specific path to normalize
> [!NOTE]
> This macro does not address OS-specific path separator issues.
**Usage:**
```cmake
macro_normalize_path(_norm_path "c:\\path\\to\\my\\directory")
```
---
### macro_create_option
**Syntax:** `macro_create_option(var_name var_value var_describe)`
**Purpose:** Creates boolean cache variable with default value.
**Parameters:**
- `var_name` [out] - Name of boolean variable
- `var_value` [in] - Default value if not yet defined
- `var_describe` [in] - Description for CMake cache
**Usage:**
```cmake
macro_create_option(ENABLE_LOGGING ON "Enable application logging")
macro_create_option(BUILD_TESTS OFF "Build unit tests")
```
---
### macro_add_source
**Syntax:** `macro_add_source(result_list src_base_dir ...)`
**Purpose:** Adds existing source files to a list based on base directory.
**Parameters:**
- `result_list` [in, out] - Variable containing list of source files
- `src_base_dir` [in] - Base directory of source files
- `${ARGN}` [in] - List of source files relative to base directory
**Usage:**
```cmake
set(MY_SOURCES)
macro_add_source(MY_SOURCES
"${PROJECT_SOURCE_DIR}/src"
main.cpp
util.cpp
handler.cpp)
```
---
### addStaticLib_C
**Syntax:** `addStaticLib_C(target_name source_list)`
**Purpose:** Wrapper for `addStaticLibEx_C` with no aliasing and automatic Areg Framework linking.
**Parameters:**
- `target_name` [in] - Name of static library
- `source_list` [in] - List of C source files
**Usage:**
```cmake
set(C_SOURCES utils.c helpers.c)
addStaticLib_C(mylib "${C_SOURCES}")
```
---
## Platform Defines
### POSIX
**Purpose:** Enables Areg Framework compilation with POSIX APIs.
**Auto-set:** Yes (when using GCC or Clang on Linux/macOS/Cygwin)
**When to use:**
- Building on Linux
- Building on macOS
- Building on Cygwin (Windows POSIX environment)
**CMake example:**
```bash
cmake -B ./build -DAREG_COMPILER_FAMILY=gnu
```
**Compilers:**
- GCC (`g++`)
- Clang (`clang++`)
- Cygwin GCC
**Mutual exclusivity:** Cannot be used with `WINDOWS`
---
### WINDOWS
**Purpose:** Enables Areg Framework compilation with Windows APIs.
**Auto-set:** Yes (when using MSVC or Clang for Windows)
**When to use:**
- Building on Windows with Visual Studio
- Building with MSVC compiler
- Building with Clang for Windows (`clang-cl`)
**CMake example:**
```bash
cmake -B ./build -DAREG_COMPILER_FAMILY=msvc
```
**Visual Studio:** Automatically set when building with Visual Studio.
**Compilers:**
- MSVC (`cl`)
- Clang for Windows (`clang-cl`)
**Mutual exclusivity:** Cannot be used with `POSIX`
---
## Build Type Defines
### DEBUG
**Purpose:** Enables Debug build configuration with debugging symbols and no optimization.
**Auto-set:** Yes (when `CMAKE_BUILD_TYPE=Debug` or Visual Studio Debug configuration)
**When to use:**
- Development and debugging
- Testing and diagnostics
- Analyzing issues
**CMake example:**
```bash
cmake -B ./build -DAREG_BUILD_TYPE=Debug
# or
cmake -B ./build -DCMAKE_BUILD_TYPE=Debug
```
**Visual Studio:** Select **Debug** configuration from toolbar.
**Impact:**
- Debugging symbols included
- No optimization
- Assertions enabled
- Larger binary size
**Mutual exclusivity:** Cannot be used with `NDEBUG`
---
### NDEBUG
**Purpose:** Enables Release build configuration with optimization and no debugging symbols.
**Auto-set:** Yes (when `CMAKE_BUILD_TYPE=Release` or Visual Studio Release configuration)
**When to use:**
- Production deployment
- Performance testing
- Final binary distribution
**CMake example:**
```bash
cmake -B ./build -DAREG_BUILD_TYPE=Release
# or
cmake -B ./build -DCMAKE_BUILD_TYPE=Release
```
**Visual Studio:** Select **Release** configuration from toolbar.
**Impact:**
- No debugging symbols
- Full optimization
- Assertions disabled
- Smaller, faster binary
**Mutual exclusivity:** Cannot be used with `DEBUG`
---
## Areg Framework Library Defines
### Export Defines (Building areg Library)
#### EXP_AREG_DLL
**Purpose:** Exports symbols when building `areg` as a shared library (DLL/SO).
**Auto-set:** Yes (when building areg library as shared)
**When to use:**
- Building areg shared library
- Creating dynamic library
**CMake example:**
```bash
cmake -B ./build -DAREG_BINARY=shared
```
**Visual Studio:** Default configuration for areg library.
**Mutual exclusivity:** Cannot be used with `EXP_AREG_LIB`
> [!NOTE]
> This define is only relevant when **building** the areg library itself, not when using it in applications.
---
#### EXP_AREG_LIB
**Purpose:** Exports symbols when building `areg` as a static library.
**Auto-set:** Yes (when building areg library as static)
**When to use:**
- Building areg static library
- Creating standalone library
**CMake example:**
```bash
cmake -B ./build -DAREG_BINARY=static
```
**Visual Studio:** Manually set in areg project properties.
**Mutual exclusivity:** Cannot be used with `EXP_AREG_DLL`
> [!NOTE]
> This define is only relevant when **building** the areg library itself, not when using it in applications.
---
## Areg Logger Library Defines
### Export Defines (Building areglogger Library)
#### EXP_LOGGER_DLL
**Purpose:** Exports symbols when building `areglogger` as shared library.
**Auto-set:** Yes (when building areglogger library as shared)
**When to use:**
- Building areglogger shared library
**CMake example:**
```bash
cmake -B ./build -DAREG_LOGGER_BINARY=shared
```
**Visual Studio:** Default configuration for areglogger library.
**Mutual exclusivity:** Cannot be used with `EXP_LOGGER_LIB`
> [!NOTE]
> This define is only relevant when **building** the areglogger library itself.
---
#### EXP_LOGGER_LIB
**Purpose:** Exports symbols when building `areglogger` as static library.
**Auto-set:** Yes (when building areglogger library as static)
**When to use:**
- Building areglogger static library
**CMake example:**
```bash
cmake -B ./build -DAREG_LOGGER_BINARY=static
```
**Visual Studio:** Manually set in areglogger project properties.
**Mutual exclusivity:** Cannot be used with `EXP_LOGGER_DLL`
> [!NOTE]
> This define is only relevant when **building** the areglogger library itself.
---
### BIT32
**Purpose:** Configures build for 32-bit systems.
**Auto-set:** Yes (based on compiler and platform selection)
**When to use:**
- Building for 32-bit systems
- Legacy system support
**CMake example:**
```bash
cmake -B ./build -DAREG_PROCESSOR=x86
```
**Visual Studio:** Select **Win32** platform.
**Mutual exclusivity:** Cannot be used with `BIT64`
---
### BIT64
**Purpose:** Configures build for 64-bit systems.
**Auto-set:** Yes (based on compiler and platform selection)
**When to use:**
- Building for 64-bit systems (recommended)
- Modern system deployment
**CMake example:**
```bash
cmake -B ./build -DAREG_PROCESSOR=x64
```
**Visual Studio:** Select **x64** platform.
**Mutual exclusivity:** Cannot be used with `BIT32`
---
## Log Viewing with Lusan
**Lusan** is a GUI application for real-time log monitoring and analysis. It connects to `logcollector` to display logs from all connected applications with advanced filtering and visualization features.
**Features:**
- Real-time log viewing from multiple applications
- Advanced filtering by priority, scope, and text
- Color-coded log levels
- Search and export capabilities
- Timeline visualization
**Prerequisites:**
- `logcollector` service running
- Applications configured for remote logging
**See:** [Lusan Live Log Viewer Guide](./06f-lusan-live-logging.md) for complete setup and usage.
> [!TIP]
> Lusan provides a professional GUI alternative to viewing log files. It's part of the Areg SDK and developed in [areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools) repository.
---
## Running Log Observer
### Start in Console Mode
**Basic usage:**
```bash
./logobserver
```
**Expected output:**
```
Areg Log Observer console application ...
---------------------------------------------------------------------------------------------
The log observer is initialized, type '-r' to connect.
Type '-q' or '--quit' to quit the application ...:
```
---
### Start with Custom Configuration
**Specify configuration file:**
```bash
./logobserver --load="./config/custom.init"
```
---
### Connect and Start Receiving
**Once started, activate log reception:**
Type `-r` or `--restart`:
```
Areg Log Observer console application ...
---------------------------------------------------------------------------------------------
Log observer triggered connection.
Type '-q' or '--quit' to quit the application ...:
```
**Check connected applications:**
Type `-n` or `--instances`:
```
Areg Log Observer console application ...
---------------------------------------------------------------------------------------------
List of connected instances ...
Type '-q' or '--quit' to quit the application ...:
---------------------------------------------------------------------------------------------
Nr. | Inst. ID | Bits | Scopes | Name
---------------------------------------------------------------------------------------------
1. | 257 | x64 | 87 | 19_pubclient.exe
---------------------------------------------------------------------------------------------
```
---
### Stop Receiving
**Pause log reception:**
Type `-x` or `--stop`:
```
Areg Log Observer console application ...
---------------------------------------------------------------------------------------------
Log observer stops, type '-r' to resume.
Type '-q' or '--quit' to quit the application ...:
```
Type `-r` again to resume.
---
### Console Mode (Development/Testing)
For development or testing, run Log Collector in console mode:
```bash
./logcollector --console
```
**Use cases:**
- Development and debugging
- Testing configuration changes
- Temporary log collection
> [!NOTE]
> For production deployment, use system service mode. Console mode is intended for development and testing only.
---
## 2. How It Works
The persistence module reads plain-text configuration files (e.g., [areg.init](./../../framework/areg/resources/areg.init)) and stores key-value pairs with wildcard resolution support. Applications query this store during initialization to configure components, logging, and runtime behavior.
**Processing Pipeline**
1. **Load**: Read configuration file from disk or embedded resource
2. **Parse**: Extract key-value pairs using syntax rules defined below
3. **Store**: Populate internal key-value store with section-based organization
4. **Resolve**: When queried, return module-specific value or fall back to wildcard (`*`) default
5. **Query**: Application components retrieve resolved values by key
**Wildcard Resolution**: When an application queries a key, the persistence module first searches for a module-specific entry (e.g., `log::myapp::scope::*`). If not found, it falls back to the wildcard entry (e.g., `log::*::scope::*`). This enables global defaults with selective overrides.
### Storage Architecture
The Areg persistence module organizes key-value pairs into three distinct storage sections, each with different mutability and lifetime characteristics:
#### Read-Only Section
**Purpose**: Global configuration applicable to all modules.
- **Scope**: Keys with wildcard module (`*`) — e.g., `log::*::scope::areg_*`
- **Mutability**: Immutable after initialization
- **Persistence**: Fixed values that remain constant across process restarts
- **Use Case**: Framework-wide defaults, system-level settings, shared logging scopes
**Example**:
```text
log::*::scope::areg_* = NOTSET # Fixed for all applications
log::*::layout::enter = %d: [ %t %x.%z: Enter -->]%n
router::*::address::tcpip = localhost # Fixed router address
```
When any module queries `log::*::scope::areg_*`, it receives the same immutable value (`NOTSET`).
#### Writable Section
**Purpose**: Module-specific configuration that can be modified and persisted.
- **Scope**: Keys with specific module names — e.g., `log::myapp::scope::*`
- **Mutability**: Applications can modify values at runtime
- **Persistence**: Changes are written to the file system and survive process restarts
- **Use Case**: User preferences, feature toggles, runtime-adjustable settings
**Example**:
```text
log::myapp::scope::* = INFO | SCOPE # Initial value
# Application changes to DEBUG | SCOPE at runtime
# Next startup reads: log::myapp::scope::* = DEBUG | SCOPE
```
Writable properties enable applications to store configuration state between sessions without external databases.
#### Temporary Section
**Purpose**: Runtime-only module-specific properties.
- **Scope**: Keys with specific module names, marked as temporary
- **Mutability**: Applications can modify values at runtime
- **Persistence**: **Not persisted**—changes exist only during process lifetime
- **Lifecycle**: Created on startup, destroyed on shutdown
- **Use Case**: Session state, runtime flags, ephemeral counters, dynamic behavior switches
**Example**:
```text
# Process 'myapp' sets temporary property at runtime (not in areg.init file)
log::myapp::scope::temp_debug = DEBUG | SCOPE # Exists only while process runs
# After shutdown, this property is lost
```
Temporary properties provide fast, memory-only storage for transient state without file I/O overhead.
### Section Interaction
When a module queries a key, the resolution order follows this priority:
1. **Temporary section** (module-specific, runtime-modified, not persisted)
2. **Writable section** (module-specific, runtime-modified, persisted)
3. **Read-only section** (wildcard, immutable, persisted)
**Example Resolution**:
```text
# Configuration file areg.init (read-only + writable sections)
log::*::scope::* = WARN # Read-only default
log::myapp::scope::* = INFO | SCOPE # Writable initial value
# Runtime (temporary section)
# Application 'myapp' sets temporary override:
# log::myapp::scope::* = DEBUG | SCOPE
# Query result for 'myapp': DEBUG | SCOPE (temporary takes precedence)
# After restart: INFO | SCOPE (temporary lost, writable persists)
# Other apps query result: WARN (read-only default)
```
This three-tier architecture balances flexibility (writable + temporary) with safety (read-only defaults) while minimizing file system writes (temporary properties never touch disk).
**Thread Safety**: The persistence module is read-only after initialization, allowing lock-free concurrent access from multiple threads.
---
## 4. Property Keys
### Anatomy of a Key
```text
section::module::property[::position]
```
| Component | Required | Description | Examples |
|-----------|----------|-------------|----------|
| **section** | Yes | Configuration domain | `log`, `router`, `logger`, `config` |
| **module** | Yes | Target executable name or `*` for all | `myapp`, `mtrouter`, `*` |
| **property** | Yes | Setting identifier | `scope`, `enable`, `layout`, `address` |
| **position** | No | Sub-category for complex settings | `areg_*`, `tcpip`, `enter`, `message` |
### Key Hierarchy Examples
```text
log::*::scope::* # Global scope settings for all executables
log::myapp::scope::* # Scope settings specific to 'myapp' executable
log::myapp::scope::database_* # Database-related scopes in 'myapp'
router::*::address::tcpip # TCP/IP address for message router
```
### Wildcard Behavior
Using `*` in the module position creates **global defaults** that apply to all executables unless overridden by module-specific entries. Wildcards in the position field match patterns (e.g., `areg_*` matches all scopes starting with `areg_`).
**Resolution Priority**: Module-specific keys take precedence over wildcard keys.
```text
log::*::scope::areg_* = NOTSET # All apps: disable scopes starting with 'areg_'
log::*::scope::* = WARN # All apps: default WARN for other scopes
log::myapp::scope::* = DEBUG # 'myapp': override to DEBUG
log::mtrouter::scope::* = NOTSET # 'mtrouter': no logging
```
**Resolution Algorithm**:
1. Query for `log::::scope::*` where `` is the requesting application
2. If module-specific key exists, return its value
3. If not found, search for `log::*::scope::*` (wildcard)
4. If wildcard exists, return its value
5. If neither exists, return default/empty value
This mechanism enables **one configuration file, many applications**—critical for IPC deployments where updating multiple config files is error-prone.
---
## 5. Property Values
### Value Syntax
Values begin immediately after `=` and terminate at:
- Semicolon (optional) `;`
- Comment marker `# `
- End of line
### Single Value
```text
log::*::enable = true
router::*::port::tcpip = 8181;
log::*::file::append = false
```
### Multi-Value Lists
Use pipe `|` to specify multiple values (logical OR relationship):
```text
log::*::scope::* = DEBUG | SCOPE
log::*::target = remote | file | debug | db
router::*::connect = tcpip
```
**Parsing Behavior**: The persistence module returns multi-value entries as an array or list type (implementation-dependent).
### Special Characters
Values support all printable ASCII characters. To include literal `#` or `;` in a value, ensure no space precedes `#`, or use `;` only as a terminator.
```text
config::*::version = 2.0.0 # Valid: version number
log::*::file::location = ./logs/%appname%_%time%.log # Valid: masks
```
---
## 7. Best Practices
### Key Naming Conventions
- Use lowercase ASCII letters, digits, and underscores only
- Prefer descriptive names: `database_connection` over `db_conn`
- Group related settings under common sections: `log::`, `router::`, `logger::`
- Use wildcards in position for pattern matching: `scope::database_*` for all database scopes
### Value Guidelines
- Keep values simple and atomic (avoid encoding complex structures)
- Use multi-value lists for enumeration sets: `DEBUG | SCOPE`
- Document value units in comments: `port = 8181 # Port number`
- Use masks in file paths: `%appname%_%time%.log` for timestamped files
### File Organization
```text
# Structure configuration files in sections:
# 1. Global defaults (using *) - Read-Only Section
# 2. Application-specific overrides - Writable Section
# 3. Remote service configuration
# 4. Module-specific settings
```
### Choosing Storage Types
**Use Read-Only (wildcard keys) for:**
- Framework defaults that never change: `log::*::layout::*`
- System-wide logging configurations: `log::*::scope::areg_*`
- Service endpoints: `router::*::address::tcpip`
- Constants shared across all applications
**Use Writable (module-specific) for:**
- Application-specific scope settings: `log::myapp::scope::*`
- Per-module log levels that may change between sessions
- Feature flags that persist: `log::myapp::scope::ui_*`
- Runtime-adjustable settings that should survive restarts
**Use Temporary (runtime-only) for:**
- Session tokens and authentication state
- Real-time counters and metrics: `log::myapp::scope::temp_counter`
- Debug flags enabled at runtime without file modification
- Transient feature switches for testing
### Shared Configuration Strategy
When multiple applications share one `areg.init` file:
- Set conservative defaults with wildcards: `log::*::scope::* = NOTSET`
- Enable features selectively per application: `log::myapp::scope::* = DEBUG | SCOPE`
- Disable logging for system services: `log::mtrouter::scope::* = NOTSET`
- Place the shared file in a common location: `/etc/areg/areg.init` or `~/.config/areg/areg.init`
- Use environment variables to override the configuration file path if needed
### Performance Considerations
- Configuration files are parsed once at startup—keep files under 100KB for sub-millisecond parsing
- Use temporary properties for frequently changing values to avoid file I/O
- Writable properties trigger file updates on change—use sparingly for critical data only
- Read-only properties (wildcards) have no runtime overhead after initialization
---
## 2. Code Generator (`codegen.jar`)
### Purpose
The **service code generator** transforms service interface definitions (`.siml` files) into production-ready C++ code, eliminating manual boilerplate and ensuring interface consistency across service providers and consumers.
### Generated Code Components
- Service provider base classes and stubs
- Service consumer proxy classes
- RPC method signatures and dispatch logic
- Event notification handlers
- Attribute access methods
- Serialization/deserialization code
### Integration Model
- **Seamless CMake Integration**: Automatically invoked during project builds
- **Zero Manual Intervention**: Runs transparently as part of the build pipeline
- **Dependency Tracking**: Regenerates code only when interface definitions change
### Build and Availability
- **Build Requirement**: Java 17 or newer
- **Build Process**: Automatically compiled when building Areg SDK
- **Location**: Output directory depends on build configuration (typically `product/build//bin`)
> [!NOTE]
> Developers do not need to invoke `codegen.jar` manually. The CMake build system handles code generation automatically.
---
## Tool Ecosystem
The Areg SDK tools form an integrated development and diagnostics pipeline:
```text
Project Setup Tool
↓
Service Interface Definition (.siml)
↓
codegen.jar
↓
Generated Service Providers/Consumers
↓
Areg-based Applications (Runtime)
↓
logcollector ←→ logobserver
↓
Lusan
(Visualization & Analysis)
```
### Workflow Integration
1. **Project Creation**: Use `project-setup` to generate initial project structure
2. **Service Design**: Define service interfaces in `.siml` files (manually or via Lusan)
3. **Code Generation**: `codegen.jar` generates C++ code during build
4. **Development**: Implement business logic in generated base classes
5. **Debugging**: Use `logcollector` + `logobserver` or Lusan for runtime diagnostics
---
## 2. Usage
### Prerequisites
- **Java 17 or newer** installed and available in system PATH
- Areg SDK built (provides `codegen.jar` in the output directory)
### Service Interface Definition
Create a `.siml` file defining your service interface. A service interface consists of:
- **Data Structures**: Custom types, enumerations, imported types
- **Attributes**: Shared state accessible to all consumers
- **Requests**: Service Consumer-initiated RPC calls expecting responses
- **Responses**: Service Provider-side answers to requests
- **Broadcasts**: Service Provider-initiated event to all connected and subscribed consumers
**Example**: `HelloService.siml`
```xml
Simple greeting serviceRequest a personalized greetingGreeting response
```
For detailed `.siml` syntax, see [Service Interface Documentation](./ServiceInterface.md).
### Command-Line Invocation
```bash
java -jar codegen.jar --doc= --root= --target=
```
**Parameters**:
- `--doc`: Path to `.siml` service interface definition file
- `--root`: Root directory for generated files (typically project source directory)
- `--target`: Relative path within root for generated code (e.g., `generated/services`)
**Example**:
```bash
java -jar codegen.jar \
--doc=./services/HelloService.siml \
--root=./src \
--target=generated
```
Generated files appear in: `./src/generated/`
### Help and Options
```bash
java -jar codegen.jar --help
```
Displays all available command-line options and usage information.
> [!TIP]
> Use the [Lusan GUI tool](https://github.com/aregtech/areg-sdk-tools) to visually design service interfaces. Lusan provides an intuitive graphical editor for `.siml` files, eliminating the need to write XML manually.
---
## 3. Build Integration
### Automated Integration with CMake
Areg SDK provides CMake functions in [functions.cmake](./../../conf/cmake/functions.cmake) to seamlessly integrate code generation into the build process:
#### `addServiceInterface`
Generates code in `${AREG_GENERATE_DIR}` with automatic directory structure:
```cmake
addServiceInterface()
```
**Behavior**:
- Creates directory structure based on `.siml` file location
- Generates C++ source and header files
- Compiles files into a static library
- Makes library available for linking
**Example**:
```cmake
addServiceInterface(HelloServiceLib ./services/HelloService.siml)
macro_declare_executable(HelloService HelloServiceLib main.cpp provider.cpp)
```
#### `addServiceInterfaceEx`
Generates code in a custom location:
```cmake
addServiceInterfaceEx()
```
Use when you need control over the output directory structure.
#### `macro_add_service_interface`
Low-level function for advanced scenarios:
```cmake
macro_add_service_interface()
```
Allows specifying custom code generator location and output directory.
### Integration with Microsoft Visual Studio
For Visual Studio projects without CMake, see the dedicated guide:
📘 [Integrating Areg Framework with Microsoft Visual Studio](./02c-msvc-integrate.md)
Manual integration steps:
1. Run `codegen.jar` from command line or custom build step
2. Add generated files to a static library project
3. Link the library with your application projects
---
## 4. Workflow Examples
### CMake-Based Workflow
**Step 1: Create Service Interface**
Define `services/HelloService.siml` following the [Service Interface structure](./ServiceInterface.md).
**Step 2: Configure CMake Build**
In your `CMakeLists.txt`:
```cmake
# Include Areg SDK
include(/areg.cmake)
# Generate service interface code and create static library
addServiceInterface(HelloServiceLib ./services/HelloService.siml)
# Create executable linking the generated library
macro_declare_executable(
HelloService # Executable name
HelloServiceLib # Generated service library
main.cpp # Application sources
ServiceProvider.cpp
)
```
**Step 3: Implement Business Logic**
Use generated base classes:
```cpp
#include "generated/HelloServiceStub.hpp"
class ServiceProvider : public HelloServiceStub {
public:
// Implement request handler
virtual void requestGreeting(const String& name) override {
// Business logic here
String greeting = "Hello, " + name + "!";
responseGreeting(greeting);
}
};
```
**Step 4: Build Project**
```bash
cmake -B ./build
cmake --build ./build
```
Code generation happens automatically during the build process.
### Visual Studio Workflow
**Step 1: Create Service Interface**
Define `services/HelloService.siml` following the [Service Interface structure](./ServiceInterface.md).
**Step 2: Run Code Generator**
```bash
java -jar codegen.jar ^
--doc=services/HelloService.siml ^
--root=src ^
--target=generated
```
**Step 3: Add Generated Files to Project**
1. Create a static library project in Visual Studio
2. Add generated files from `src/generated/` to the project
3. Compile the library
4. Link it with your application project
**Step 4: Implement Business Logic**
Same as CMake workflow—inherit from generated stubs and implement service methods.
---
## Summary
The `codegen.jar` tool is a cornerstone of Areg SDK development, transforming service interface definitions into production-ready C++ code. By automating boilerplate generation, enforcing interface consistency, and integrating seamlessly with modern build systems, it enables developers to build robust, maintainable distributed applications efficiently.
**Key Takeaways**:
- **Automates** service interface code generation from `.siml` definitions
- **Eliminates** hundreds of lines of boilerplate per service
- **Ensures** type-safe, standards-compliant communication code
- **Integrates** seamlessly with CMake and Visual Studio workflows
- **Accelerates** development cycles and reduces errors
For advanced service interface design and visual editing, explore the [Lusan GUI tool](https://github.com/aregtech/areg-sdk-tools).
---
## Running Lusan
### Standalone Execution
```bash
cd build/bin
./lusan
```
Lusan can run independently for:
- Offline log file analysis
- Service interface design
- Configuration editing
### With Log Collector
For live log monitoring, run `logcollector` alongside Lusan:
**Terminal 1 (Log Collector)**:
```bash
cd build/bin
./logcollector
```
**Terminal 2 (Lusan)**:
```bash
cd build/bin
./lusan
```
**Terminal 3 (Your Application)**:
```bash
cd your-application/build
./your-app
```
Lusan connects to `logcollector`, which aggregates logs from all Areg-based applications on the network.
### Configuration
Edit `areg.init` to configure:
- Log collector IP address and port (default: `localhost:8282`)
- Message router IP address and port (default: `localhost:8181`)
- Logging scopes and priorities
See [Key-Value Data Persistence](./key-value-persistence.md) for configuration syntax.
---
## Summary
Lusan is a self-contained graphical tool built on Areg and Qt frameworks. The build process is fully automated:
- **CMake Workflow**: Command-line build for CI/CD and headless systems
- **Qt Creator Workflow**: IDE-based development with integrated debugging
- **Automatic Dependencies**: Fetches and builds Areg SDK if not present
- **Self-Contained Output**: All runtime libraries included in `build/bin/`
### Build Checklist
- ✅ C++17 compiler installed
- ✅ CMake 3.20+ available
- ✅ Qt 5.x or 6.x installed
- ✅ Internet access for initial build
- ✅ 4+ GB RAM for parallel builds
### Next Steps
After building Lusan:
1. Run `logcollector` for live log monitoring
2. Launch Lusan and connect to log collector
3. Start your Areg applications
4. Monitor logs in real-time or design service interfaces
For detailed usage instructions, refer to the Lusan user guide (coming soon).
---
## What Is Lusan Used For
### Primary Use Cases
**Service Interface Development**
- Design and maintain service interface documents (`.siml` files)
- Define data types, attributes, methods, and constants
- Validate interfaces before code generation
- Visual editing eliminates manual XML authoring
**Real-Time System Monitoring**
- Monitor logs from distributed applications in real time
- Track request/response flows across service providers and consumers
- Correlate events across multiple components and processes
- Filter and search log streams dynamically
**Offline Diagnostics**
- Analyze recorded logs without live system access
- Investigate intermittent issues and rare edge cases
- Share log files with team members for collaborative debugging
- Perform post-mortem analysis of production incidents
**Runtime Configuration**
- Control logging scopes and priorities without restarting applications
- Adjust log verbosity for specific components on-the-fly
- Save configuration changes for subsequent application launches
### Target Users
- **Application Developers**: Daily development and debugging
- **System Integrators**: Multi-component system testing
- **DevOps Engineers**: Production troubleshooting
- **QA Teams**: Test scenario analysis
---
## Prerequisites
### Required Software
Before using Lusan, ensure the following are available:
| Component | Requirement | Notes |
|-----------|-------------|-------|
| **Lusan** | Built and installed | From [areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools) |
| **Qt Libraries** | Qt 5.x or 6.x | Runtime libraries must be accessible |
| **logcollector** | Built and accessible | Required for live log monitoring |
| **Configuration** | `lusan.init` file | Network settings for log collector connection |
### Optional Components
- **Areg SDK**: For building applications to monitor
- **Service Interface Files**: `.siml` files for interface design work
- **Log Files**: Previously recorded logs for offline analysis
---
## Building Lusan
Lusan is hosted in a separate repository from the Areg SDK core:
📦 [github.com/aregtech/areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools)
### Build Process
```bash
git clone https://github.com/aregtech/areg-sdk-tools.git
cd areg-sdk-tools
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
```
### Automatic Dependency Resolution
If the Areg SDK is not installed locally, the build system automatically:
1. Fetches Areg SDK sources from GitHub
2. Builds required Areg libraries (`areg`, `aregextend`)
3. Links them with Lusan
4. Copies runtime dependencies to the output directory
> [!IMPORTANT]
> Internet access is required during the initial build if Areg SDK is not present locally.
### Building with Qt Creator
If Qt is not installed system-wide, use Qt Creator for simplified configuration:
1. **Open Project**: Launch Qt Creator and open `areg-sdk-tools/CMakeLists.txt`
2. **Configure Kit**: Select compiler (GCC, Clang, MSVC, MinGW) and Qt version
3. **Set Build Type**: Choose Debug or Release
4. **Build**: Qt Creator automatically resolves Qt dependencies and builds all components
All required dependencies, including Areg Framework libraries and Qt runtime libraries, are automatically copied to the build directory.
### Build Output
After successful build, find executables in `build/bin/`:
- `lusan` - Main application
- `logcollector` - Log collection service
- `mtrouter` - Message router service
- Required Qt and Areg runtime libraries
**For detailed build instructions**, see [Building Lusan with CMake or Qt Creator](./06c-build-lusan.md).
---
## Starting Lusan
### First Launch
When Lusan is launched for the first time, it prompts you to create a new workspace:
**Initial Setup Steps**:
1. Click **Create New Workspace**
2. Specify workspace (project) directory
3. Optionally configure additional directories (sources, includes, logs)
4. Click **OK** to create and load the workspace
### Subsequent Launches
On subsequent starts, Lusan:
- Displays the list of available workspaces
- Automatically selects the last accessed workspace as default
- Allows switching between workspaces via the workspace selector
### Launch from Command Line
```bash
cd build/bin
./lusan
```
---
## Workspace Concept
### What Is a Workspace?
A **workspace** in Lusan defines the project environment and organizes all project-related resources. It serves as the central configuration unit that groups together:
- **Project Directory** (workspace root) - Required
- **Source Code Directory** - Optional, for browsing service interfaces
- **Include Directory** - Optional, for referenced header files
- **Delivery Directory** - Optional, for third-party deliverables
- **Log Directory** - Optional, default location for saved logs
### Workspace Benefits
**Project Isolation**: Each workspace maintains independent settings and configurations
**Multi-Project Support**: Switch between different projects without reconfiguration
**Team Collaboration**: Share workspace configurations across development teams
**Flexible Structure**: Adapt to various project layouts and directory organizations
### Visual Organization
Within the workspace, Lusan provides:
- **Workspace Navigation**: Browse project directories in the navigation pane
- **Service Interface Files**: Access and edit `.siml` definitions
- **Log Files**: Open saved logs from the log directory
- **Quick Access**: Frequently used files and locations
---
## Setting Up a Workspace
### Creating a New Workspace
**Method 1: Startup Dialog**
- Launch Lusan for the first time
- Click **Create New Workspace** in the welcome dialog
- Specify workspace directory and optional paths
**Method 2: Menu Access**
- Open Lusan with an existing workspace
- Navigate to **File → New Workspace**
- Configure workspace settings
- Save and switch to the new workspace
### Workspace Configuration
When creating a workspace, specify:
**Required**:
- **Workspace Directory**: Root directory of your project
**Optional**:
- **Source Directory**: Location of `.cpp`, `.hpp` files
- **Include Directory**: Location of header files
- **Delivery Directory**: Third-party libraries and deliverables
- **Log Directory**: Default location for saved log files
All paths can be absolute or relative to the workspace directory.
### Workspace Persistence
Workspace configurations are automatically saved and include:
- Directory paths
- Log collector connection settings
- UI preferences (window layout, filters, etc.)
- Recently opened files
### Directory Configuration Options
**Project Directory** (Required)
- The main project directory displayed in the workspace
- Cannot be changed after workspace creation
- Other directories can be located anywhere on the file system (inside or outside this directory)
**Source Directory** (Optional)
- Location where source code files are stored
- Service interface files (`.siml`), C++ source files (`.cpp`), and headers (`.hpp`) are typically found here
- Can be a subdirectory of the project directory or a completely separate location
- Used for browsing and opening source files and service definitions
**Include Directory** (Optional)
- Location of C++ header files when source and include directories are separated
- Common in projects with `src/` and `include/` directory structures
- Can point to external dependencies (e.g., Areg SDK framework headers)
- Can be located anywhere on the file system
- Used for browsing header files
**Delivery Directory** (Optional)
- Location of third-party deliverables and external dependencies
- Can point to system-wide installations or user-specific directories
- Used for tracking external libraries and tools (e.g., Qt installation or thir-party service interface directory)
- Can be located anywhere on the file system
**Log Directory** (Optional)
- Default location where Lusan saves log files
- Can be any location on the file system
- Used as the default path in save/load log file dialogs
### Directory Path Flexibility
All directories (except the project directory) can be:
- Subdirectories of the project directory
- Located outside the project directory
- Absolute paths on the file system
- Paths to system-wide installations
- User-specific directories
Service interface files (`.siml`) can be located in any of these configured directories, and Lusan will display them in the workspace navigation.
### Example Configuration (Linux)
```
Project Directory: /home/user/projects/areg-sdk-demo
Source Directory: /home/user/projects/areg-sdk-demo/demo
Include Directory: /home/user/areg-sdk/framework
Delivery Directory: /home/user/myproj/services
Log Directory: /home/user/logs/areg-demo
```
In this example:
- Sources are in a subdirectory of the project
- Include directory points to a separate Areg SDK installation
- Delivery directory points to a service interface directory in the user's home delivered by third-party company
- Log directory is in the user's home directory
### Updating Directory Paths
1. Open **Tools → Options → Directories**
2. Modify desired directory paths
3. Click **Apply** or **OK**
4. Changes take effect immediately
Directory paths are saved to the workspace configuration file.
### Managing Multiple Workspaces
Access workspace management: **Tools → Options → Workspaces**
**Available Actions**:
- **Add Workspace**: Register an existing workspace
- **Remove Workspace**: Delete workspace from list (files are not deleted)
- **Set Default**: Choose default workspace for startup
- **Switch Workspace**: Load a different workspace
> [!NOTE]
> You cannot remove the currently active workspace from the list. Switch to another workspace first.
### Configuration Parameters
**Host Address**
- IP address or hostname of the machine running `logcollector`
- Default: `localhost` (same machine)
- Example: `192.168.1.100` for remote log collector
**Port Number**
- TCP port where `logcollector` listens for connections
- Default: `8282` (standard Areg log collector port)
- Must match the port configured in `areg.init` on the log collector side
**Connection Timeout**
- Maximum time to wait for connection establishment
- Default: 5 seconds
- Increase for slow or unreliable networks
### Testing Connection
1. Configure host address and port
2. Click **Test** button
3. View connection status in **Test Status** box
**Status Messages**:
- ✅ **Connected**: Log collector is reachable
- ❌ **Connection Failed**: Check network, firewall, or log collector status
- ⏱️ **Timeout**: Increase timeout or verify log collector is running
### Saving Connection Settings
1. Configure connection parameters
2. Test connection (recommended)
3. Click **OK** or **Apply**
Settings are saved to `lusan.init` configuration file and persist across sessions.
### Troubleshooting Connection Issues
**Log Collector Not Running**
```bash
# Start log collector
cd build/bin
./logcollector
```
**Firewall Blocking Connection**
- Allow TCP port 8282 in firewall settings
- Verify with: `telnet 8282`
**Incorrect Configuration**
- Verify `areg.init` on log collector side:
```text
logger::*::address::tcpip =
logger::*::port::tcpip = 8282
```
---
## Core Workflows
### Service Interface Design
Lusan provides a visual editor for creating and maintaining service interface documents (`.siml` files).
#### Creating a Service Interface
1. **Open Workspace**: Load workspace containing your project
2. **Create Interface**: Navigate to **File → New → Service Interface**
3. **Configure Service**:
- **Overview**: Service name, version, description
- **Data Types**: Define structures, enumerations, type aliases
- **Attributes**: Shared state accessible to all consumers
- **Methods**: Requests, responses, broadcasts
- **Constants**: Service-level constants
- **Includes**: External type definitions
4. **Save Interface**: Save as `.siml` file in workspace source directory
#### Editing Service Interfaces
- **Open Existing**: Browse workspace navigation pane or **File → Open**
- **Visual Editor**: Use tabs and forms to modify interface components
- **Validation**: Real-time syntax and consistency checking
- **Save Changes**: Ctrl+S or **File → Save**
#### Code Generation Integration
Service interfaces created in Lusan are consumed by the Areg code generator during build:
```cmake
addServiceInterface(MyServiceLib ./services/MyService.siml)
```
**For detailed interface design**, see [Creating Service Interface Documents with Lusan](./06e-lusan-service-interface.md).
### Live Log Monitoring
Monitor logs from running Areg applications in real time.
#### Setting Up Live Monitoring
**Prerequisites**:
1. Log collector running: `./logcollector`
2. Lusan connected to log collector (see configuration above)
3. Areg applications running with remote logging enabled
**Steps**:
1. **Start Log Collector**: Launch `logcollector` from command line
2. **Connect Lusan**: Open Lusan, verify connection indicator shows green
3. **Start Applications**: Launch your Areg-based applications
4. **View Logs**: Logs appear in real time in Lusan's log viewer
#### Log Viewer Features
**Filtering**
- Filter by log priority (DEBUG, INFO, WARN, ERROR, FATAL)
- Filter by scope name or pattern
- Filter by module (process) name
- Filter by thread ID
- Combine multiple filters
**Searching**
- Text search across log messages
- Regular expression support
- Highlight search results
**Correlation**
- Track request/response pairs across components
- Follow execution flow through distributed system
- Color-code related log entries
**Time Navigation**
- Jump to specific timestamp
- Navigate to next/previous occurrence
- Bookmark important log entries
#### Live Log Controls
**Pause/Resume**: Freeze log stream for detailed inspection
**Clear**: Clear current log buffer
**Save**: Save current logs to file for offline analysis
**Auto-Scroll**: Automatically scroll to newest log entries
### Offline Log Analysis
Analyze previously recorded logs without live system connection.
#### Loading Log Files
**Method 1: File Menu**
1. Navigate to **File → Open Log File**
2. Browse to log file location
3. Select file and click **Open**
**Method 2: Drag and Drop**
- Drag log file from file manager
- Drop onto Lusan window
**Method 3: Workspace Navigation**
- Browse to log directory in workspace navigation pane
- Double-click log file
#### Offline Analysis Features
**Full Search and Filter**
- All filtering capabilities available in offline mode
- Search entire log file regardless of size
- No real-time constraints
**Post-Mortem Debugging**
- Trace execution leading to failures
- Identify root cause of intermittent issues
- Analyze timing and sequence of events
**Sharing and Collaboration**
- Share log files with team members
- Reproduce issues on different machines
- Archive logs for future reference
**Performance Analysis**
- Identify bottlenecks and slow operations
- Measure request/response times
- Analyze system behavior under load
### Adjusting Log Scope Priorities
**Steps**:
1. **Connect to Live System**: Ensure connection to log collector
2. **Navigate Scopes**: Navigate Scopes on left panel
3. **Select Application**: Choose target application
4. **Modify Priorities**:
- Enable/disable scopes: Check/uncheck scope entries
- Change priority levels: Select DEBUG, INFO, WARN, ERROR, FATAL, or NOTSET
- Click on save button to apply changes on target.
5. The current settings are applied immediately to the running application and will be applied on next start(s).
### Runtime Configuration Benefits
- **No Restarts Required**: Change logging behavior on-the-fly
- **Targeted Debugging**: Enable verbose logging for specific components only
- **Performance Optimization**: Reduce log overhead by disabling unnecessary scopes
- **Production Troubleshooting**: Increase logging temporarily without deployment
---
## Best Practices
### Workspace Management
**One Workspace Per Project**
- Create separate workspaces for different projects or systems
- Maintains clean separation of configurations and settings
- Prevents cross-project interference
**Meaningful Directory Structure**
```
project-workspace/
├── services/ # Service interface definitions
├── src/ # Source code
├── include/ # Header files
├── logs/ # Saved log files (better ourside of project)
└── config/ # Configuration files
```
**Version Control**
- Keep service interface files (`.siml`) under version control
- Exclude workspace-specific settings (`.lusan/*`) from VCS
- Share workspace templates across team members
### Service Interface Design
**Incremental Development**
- Start with minimal interface, expand as needed
- Validate frequently during design
- Use descriptive names for methods and attributes
**Documentation**
- Add descriptions to all service components
- Document parameter meanings and constraints
- Include usage examples in interface documentation
**Versioning**
- Use semantic versioning for service interfaces
- Update version numbers when making incompatible changes
- Maintain backward compatibility when possible
### Log Management
**Strategic Recording**
- Record logs for complex test scenarios
- Save logs before reproducing intermittent issues
- Archive logs from production incidents
**Dynamic Verbosity**
- Adjust log verbosity dynamically instead of restarting applications
- Enable verbose logging only for components under investigation
- Reduce log noise in stable components
**Efficient Filtering**
- Use specific scope patterns instead of wildcard searches
- Combine multiple filters for precise results
- Save commonly used filter configurations
---
## Summary
Lusan provides a **comprehensive workspace-driven environment** for developing, configuring, and analyzing Areg-based distributed systems. By integrating service interface design, live observability, offline analysis, and runtime control in a unified tool, Lusan significantly improves developer productivity and system insight.
### Key Capabilities
- **Visual Service Design**: Create `.siml` interface definitions without manual XML editing
- **Centralized Logging**: Aggregate logs from distributed applications in real time
- **Dynamic Configuration**: Adjust logging behavior without restarting applications
- **Offline Analysis**: Debug and investigate issues using recorded logs
- **Workspace Management**: Organize projects with flexible directory structures
### Integration with Areg SDK
Lusan is an essential component of the Areg SDK toolchain:
- Service interfaces designed in Lusan are consumed by `codegen.jar`
- Log collection uses `logcollector` backend service
- Configuration files follow Areg SDK standards
- Works seamlessly with Areg-based applications
Lusan is a core tool for building, testing, and maintaining reliable, scalable distributed applications with Areg SDK.
---
## Service Interface Concept in Areg SDK
A Service Interface defines the following elements:
- **Service Metadata**: Interface name, version, and category
- **Data Types**: Custom structures, enumerations, and imported types
- **Data Attributes**: Shared data with state notification behavior
- **Service Methods**: Requests, responses, and broadcasts
- **Constants**: Read-only values shared between providers and consumers
- **Include Dependencies**: External headers required by the interface
### Implementation Independence
Service Interfaces are **implementation-independent**. They describe *what* the service provides, not *how* it is implemented. This separation ensures long-term stability, compatibility, and maintainability of distributed systems.
The same interface definition is used by both Service Providers (implementing the service) and Service Consumers (using the service), guaranteeing consistent communication contracts.
---
## Why Design Service Interfaces with Lusan
Although Service Interface files (`.siml`) can be written manually as XML documents, Lusan provides a safer and more productive approach.
### Key Advantages
**Visual Modeling**
- Graphical editor eliminates manual XML editing
- Clear visual representation of service structure
- Intuitive forms for defining interface components
**Immediate Validation**
- Real-time validation of interface structure
- Prevention of invalid relationships (e.g., orphaned responses)
- Guaranteed compatibility with Areg code generator
**Reduced Errors**
- Enforces correct relationships between interface elements
- Prevents common design mistakes at creation time
- Type-safe definitions reduce runtime communication errors
**Improved Productivity**
- Faster interface design compared to manual XML editing
- Easier review, documentation, and maintenance
- Simplified collaboration across development teams
---
## Prerequisites
Before creating Service Interface documents, ensure the following:
| Requirement | Description |
|-------------|-------------|
| **Lusan** | Built and available from [areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools) |
| **Areg SDK** | Available in the development environment (for code generation) |
| **Java** | Java 17+ installed for code generation with `codegen.jar` |
| **Workspace** | Configured according to [Setup and Using Lusan](./06d-setup-lusan.md) |
**Recommended Knowledge**:
- Basic understanding of service-oriented architecture
- Familiarity with Service Provider and Service Consumer roles
- Understanding of remote method calls and event notifications
---
## Creating a Service Interface
### Launching Lusan
Start the Lusan application from the build output or installation directory:
```bash
./build/bin/lusan
```
Select or create a workspace with project-specific directories. These directories are displayed in the **Workspace** navigation tab, providing quick access to project files.
### Creating or Opening a Document
**Creating a New Interface**:
1. Navigate to **File → New → Service Interface**
2. Or click the **New Service Interface** button in the toolbar
**Opening an Existing Interface**:
1. Browse the workspace navigation pane
2. Double-click a `.siml` file
3. Or use **File → Open** to browse file system
A newly created interface is initialized with:
- **Name**: `NewServiceInterface`
- **Category**: `Private`
- **Version**: `0.0.1`
### Defining Service Metadata
In the **Overview** section, define the core metadata:
**Service Interface Category**
The category determines the accessibility scope of the service:
- **Private** (`Category="Private"`):
- Used for multithreading within a single process
- Not remotely accessible via IPC
- Faster communication (no serialization overhead)
- Suitable for internal component communication
- **Public** (`Category="Public"`):
- Supports both multithreading and inter-process communication (IPC)
- Accessible across process boundaries and devices
- Enables distributed system architectures
- Suitable for services shared between applications
> [!NOTE]
> The `Internet` category is reserved for future use and is not currently supported.
**Version**
Defines compatibility rules between Service Providers and Service Consumers:
- Use semantic versioning (e.g., `1.0.0`, `1.2.3`)
- Increment version when making interface changes
- Consumers can verify compatibility at runtime
**Description**
Optional documentation field for:
- Interface purpose and functionality
- Usage guidelines
- Version history notes
- Long-term maintenance information
**Service Interface Name**
> [!IMPORTANT]
> The Service Interface name is assigned when the document is saved for the first time.
>
> **Naming Rules**:
> - Must be a valid C++ identifier
> - May contain ASCII letters, numbers, and underscore characters
> - Must start with a letter or underscore
> - Spaces and special characters are not allowed
>
> **Note**: The Service Interface name is *not* the runtime service instance name. Multiple service instances can share the same interface.
### Defining Data Types
Custom data types are defined in the **Data Types** section.
**Supported Type Categories**:
🔹**Structures**
- Composite types with named fields
- Fields can be primitive types or other defined structures
- Supports nested structures and complex hierarchies
🔹**Enumerations**
- Named integer constants
- Define valid values for parameters and return types
- Supports custom underlying integer types
🔹**Imported Types**
- Types defined in external headers
- Allows reuse of existing C++ types
- Requires corresponding include directive
🔹**Standard Containers**
- Simple containers (arrays, lists, maps)
- Container element types can be primitive or custom
🔹**Type Availability**:
All data types are generated within the Service Interface namespace and are available for use in:
- Data attributes
- Method parameters and return values
- Constants
### Defining Data Attributes
Data Attributes represent shared state published by the Service Provider and consumed by Service Consumers.
**Attribute Configuration**:
🔹**Name**
- Unique identifier for the attribute
- Must be a valid C++ identifier
🔹**Data Type**
- Any primitive or custom type defined in the interface
- Determines the type of shared state
🔹**Notification Mode**
Controls when Service Consumers receive updates:
- **OnChange**: Sends updates only when the attribute value changes
- Reduces network traffic
- Suitable for infrequently changing state
- **Always**: Sends updates on every modification
- Guarantees delivery of all updates
- Suitable for time-series data or counters
🔹**Description**
- Optional documentation for the attribute
🔹**Attribute Behavior**:
- Service Consumers subscribe or unsubscribe to attributes at runtime
- Service Provider is responsible for publishing updates
- Supports reactive and event-driven communication patterns
- Multiple consumers can subscribe to the same attribute simultaneously
### Defining Service Methods
Service methods define callable operations and notifications.
**Method Types**:
🔹**Requests**
- Initiated by Service Consumers
- Directed to Service Provider
- May have input parameters
- Can be paired with responses
**Request Execution Modes**:
- **Blocking**: Enforces sequential execution, must be paired with a response
- **Fire-and-forget**: Allows parallel invocation, no response expected
**Advanced**: Manual request unblocking and response ordering is possible using system-generated session identifiers for complex asynchronous workflows.
🔹**Responses**
- Sent by Service Provider
- Always belong to a specific request
- May carry output parameters
- Delivered to the originating Service Consumer
- Additionally, delivered to all Service Consumer subscribed on the response
🔹**Broadcasts**
- Independent notifications from Service Provider
- Not tied to specific requests
- May carry event parameters
- Sent to all subscribed Service Consumers simultaneously
**Method Validation**:
Lusan validates:
- Request-response pairing (blocking requests must have responses)
- Parameter type consistency
- Unique method names within the interface
### Defining Constants
Constants are defined in the **Constants** section and represent shared read-only values.
**Constant Properties**:
🔹**Name**
- Unique identifier for the constant
- Must be a valid C++ identifier
🔹**Data Type**
- Any primitive or enumeration type
- Complex types are supported for constants if they can be represented as constants
🔹**Value**
- Compile-time constant value
- Must match the specified data type
🔹**Behavior**:
- Constants do not generate notifications
- Cannot be subscribed to
- Shared between Service Providers and Service Consumers
- Useful for protocol versions, buffer sizes, timeouts, etc.
### Defining Additional Includes
Additional C++ headers required by the Service Interface are defined in the **Includes** section.
**Include Configuration**:
**Header Path**
- Relative or absolute path to the header file
- Standard library headers: ``, ``, etc.
- Custom headers: `"MyCustomTypes.hpp"`
**Purpose**:
- Import external type definitions
- Reference types not defined in the Service Interface
- Reuse existing C++ types and classes
**Code Generation**:
These headers are automatically included in the generated code for both Service Provider and Service Consumer implementations.
---
## Using the Service Interface in a Project
After saving the Service Interface document (`.siml` file), integrate it into your project build system.
### CMake Integration
Add the Service Interface to your CMake build configuration:
```cmake
# Include Areg SDK
include(/areg.cmake)
# Generate service interface code and create static library
addServiceInterface(MyServiceLib ./services/MyService.siml)
# Link the library with your Service Provider or Consumer
macro_declare_executable(
MyApplication # Executable name
MyServiceLib # Generated service library
main.cpp # Application sources
MyServiceProvider.cpp
)
```
### Build Process
When you build your project:
1. **Code Generation**: CMake automatically invokes `codegen.jar`
2. **Source Generation**: C++ stub and proxy classes are generated
3. **Compilation**: Generated sources are compiled into a static library
4. **Linking**: The library is linked with your Service Provider and Consumer executables
### Generated Code
The code generator produces:
- **Service Provider Stub**: Base class for implementing the service
- **Service Consumer Proxy**: Client class for consuming the service
- **Event Classes**: Request, response, and broadcast event types
- **Serialization Code**: Data marshaling for IPC communication
**For detailed information**, see:
- [`addServiceInterface()` CMake function](./02e-cmake-functions.md#addserviceinterface)
- [Code Generator documentation](./06b-code-generator.md)
---
## Best Practices
### Design Process
**Design Before Implementation**
- Define Service Interfaces before writing Service Provider or Consumer code
- Review interfaces with the team early in the development cycle
- Validate interface completeness before code generation
**Interface Stability**
- Keep interfaces stable once deployed
- Use semantic versioning for interface changes
- Maintain backward compatibility when possible
- Document breaking changes clearly
### Communication Patterns
**Prefer Reactive Patterns**
- Use attributes and broadcasts over polling
- Leverage notification mechanisms for state changes
- Reduce network traffic with `OnChange` attributes
**Asynchronous Operations**
- Use asynchronous request patterns when possible
- Avoid blocking calls in performance-critical paths
- Consider fire-and-forget requests for non-critical operations
### Documentation
**Comprehensive Descriptions**
- Document all interface elements (attributes, methods, parameters)
- Explain expected behavior and constraints
- Include version history in service description
**Visual Reviews**
- Review interfaces visually in Lusan during code reviews
- Use Lusan to explain service architecture to new team members
- Maintain interface diagrams for system documentation
### Version Management
**Semantic Versioning**
- Use three-part version numbers: `major.minor.patch`
- Increment major version for breaking changes
- Increment minor version for backward-compatible additions
- Increment patch version for bug fixes
**Compatibility Testing**
- Test compatibility between different interface versions
- Verify runtime version checks work correctly
- Document version compatibility matrix
---
## Summary
Lusan provides a visual, validated, and developer-friendly workflow for designing Service Interfaces in Areg SDK. By defining interfaces graphically and generating code automatically, development teams reduce errors, improve consistency, and accelerate the creation of scalable distributed systems.
### Key Benefits
- **Visual Design**: Graphical editor eliminates manual XML editing
- **Validation**: Real-time validation prevents design errors
- **Code Generation**: Automatic C++ code generation from interface definitions
- **Type Safety**: Strongly-typed communication contracts
- **Productivity**: Faster development and easier maintenance
### Integration with Areg SDK
Service Interfaces created with Lusan:
- Serve as the single source of truth for communication across applications
- Are consumed by `codegen.jar` to generate C++ stub and proxy classes
- Integrate seamlessly with CMake build systems
- Enable both multithreading and IPC communication patterns
Lusan is an essential tool for building reliable, maintainable distributed applications with Areg SDK.
---
## Why Use Live Log Viewing
Live log viewing with Lusan enables:
- **Immediate Visibility**: Real-time insight into distributed system behavior
- **Centralized Aggregation**: Logs from multiple applications and machines in one view
- **Event Correlation**: Trace interactions across processes and threads
- **Runtime Debugging**: Diagnose issues without application restarts
- **Dynamic Control**: Adjust logging scopes and priorities on-the-fly
These capabilities make Lusan especially valuable for diagnosing timing issues, race conditions, and cross-component interactions in distributed systems.
---
## Prerequisites
Before starting live log monitoring, ensure the following components are available and correctly configured.
### Required Components
| Component | Description |
|-----------|-------------|
| **Lusan** | Built from [areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools) repository |
| **logcollector** | Built from Areg SDK, serves as log aggregation service |
| **Areg Applications** | Applications with logging enabled |
| **Configuration Files** | `areg.init` for applications/logcollector, `lusan.init` for Lusan |
### Configuration Requirements
Both `areg.init` (for applications and `logcollector`) and `lusan.init` (for Lusan) must define the same log service endpoint:
```text
logger::*::service = logcollector # Log collector process name
logger::*::connect = tcpip # Communication protocol
logger::*::enable::tcpip = true # Enable TCP/IP
logger::*::address::tcpip = 127.0.0.1 # IP address (default: localhost)
logger::*::port::tcpip = 8282 # Port number (default: 8282)
```
> [!IMPORTANT]
> All applications and Lusan must use the same configuration to communicate with `logcollector`.
**Example Configuration**:
- For local development: `logger::*::address::tcpip = 127.0.0.1`
- For distributed systems: `logger::*::address::tcpip = 192.168.1.100` (logcollector host IP)
---
## Step-by-Step Guide to Live Log Viewing
### Step 1: Launch the Log Collector Service
Run `logcollector` as a console application or system service on a reachable machine.
**Prerequisites**:
- `areg.init` file is accessible to `logcollector`
- TCP/IP address and port are correctly configured
- Network allows connections on the configured port
`logcollector` acts as the central aggregation point for all runtime logs.
#### Option A: Console Mode (Development)
```bash
./build/bin/logcollector
```
Console mode is recommended for development and debugging as it provides immediate feedback.
#### Option B: Service Mode (Testing or Production)
**Linux (systemd)**:
```bash
sudo systemctl enable logcollector.service
sudo systemctl start logcollector.service
```
**Windows**:
```powershell
.\logcollector.exe --install
net start logcollector
```
> [!TIP]
> For detailed information about running `logcollector` as a service, see [Areg SDK Log Collector Service](./04d-logcollector.md).
#### Verification Checklist
- ✅ Confirm successful startup in console or service logs
- ✅ Verify service listens on configured port (default: 8282)
- ✅ Ensure `areg.init` file is accessible
**Testing Port Availability**:
```bash
# Linux/macOS
netstat -an | grep 8282
# Windows
netstat -an | findstr 8282
```
#### Common Issues
**Port Already in Use**
- Change the port in `areg.init`: `logger::*::port::tcpip = 8283`
- Kill conflicting process or use a different port
**Permission Denied**
- Run with appropriate privileges (sudo on Linux, Administrator on Windows)
- Check firewall rules allow the port
**Configuration Not Found**
- Ensure `./config/areg.init` exists or specify path with environment variable
- Verify file permissions allow reading
### Step 2: Connect Lusan to Log Collector
Launch Lusan and establish a connection to the running `logcollector` service.
#### Connection Process
1. **Start Lusan Application**
```bash
cd build/bin
./lusan
```
2. **Initiate Live Logging**:
- **Method 1**: Menu → **File → New Live Logs**
- **Method 2**: Click **New Live Logs** toolbar button
- **Method 3**: Navigation pane → **Live Logs** tab → **Connect to Log Collector**
3. **Automatic Connection**:
- Lusan reads settings from `./config/lusan.init`
- Connects to configured `logcollector` address and port
- Begins recording logs in real-time mode
4. **Verify Connection Status**:
- Check for message: `Log observer connected to Log Collector service.`
- Connection indicator shows green status
#### Recorded Log Formats
Lusan automatically saves logs in two formats:
**SQLite Database (`.sqlog`)**
- Primary storage format
- Optimized for Lusan's offline log viewer
- Supports advanced filtering and queries
- **Recommended** for long-term storage and analysis
**Plain Text (`.log`)**
- Human-readable format
- Can be opened with any text editor
- Useful for quick inspection and sharing
- Compatible with standard log analysis tools
> [!TIP]
> Use SQLite database format (`.sqlog`) as primary storage for comprehensive offline analysis with Lusan's offline log viewer.
### Step 3: Start Your Areg Applications
With `logcollector` running and Lusan connected, start your Areg-based applications.
> [!NOTE]
> Applications may be started before Lusan connects. Logs will be captured once Lusan establishes connection to `logcollector`.
#### Application Configuration Requirements
**Required Configuration**:
- `areg.init` file is present and accessible
- Logging is enabled: `log::*::enable = true`
- Remote logging is enabled: `log::*::enable::remote = true`
- Log service configuration matches `logcollector` settings
**Example Application Configuration**:
```text
log::*::enable = true
log::*::enable::remote = true
log::*::remote::service = logger
log::*::scope::* = DEBUG | SCOPE
```
#### Multi-Source Logging
Lusan can monitor logs from:
- **Multiple Applications**: On the same machine
- **Distributed Processes**: On different machines across the network
- **Multiple Threads**: Within each process
- **Service Providers and Consumers**: All components in a distributed system
#### Automatic Connection
Applications automatically connect to `logcollector` at startup:
1. Application reads `areg.init` configuration
2. Establishes connection to configured log collector
3. Begins sending log messages based on scope priorities
4. Messages appear in Lusan's log viewer in real time
### Step 4: Monitor and Analyze Real-Time Logs
Once connected, logs from all applications appear in the Lusan log viewer in real time.
#### Log Viewer Features
**Real-Time Display**
- Logs appear with minimal latency (typically < 100ms)
- Automatic scrolling to newest entries
- Color-coded priority levels for visual distinction
**Log Entry Information**
Each log entry displays:
- **Timestamp**: Date and time of log generation
- **Priority**: DEBUG, INFO, WARN, ERROR, FATAL, or SCOPE
- **Source**: Application (process) name and ID
- **Thread**: Thread name and ID
- **Scope**: Logging scope (function/component identifier)
- **Message**: Log message text
**Interactive Controls**
- **Pause/Resume**: Freeze log stream for detailed inspection
- **Clear**: Clear current log buffer
- **Auto-Scroll**: Toggle automatic scrolling to newest entries
- **Export**: Save filtered logs to file
#### Log Priority Levels
| Priority | Color | Description |
|----------|-------|-------------|
| **DEBUG** | Gray | Detailed diagnostic information |
| **INFO** | Blue | General informational messages |
| **WARN** | Yellow | Warning messages (potential issues) |
| **ERROR** | Orange | Error messages (failures occurred) |
| **FATAL** | Red | Fatal errors (critical failures) |
| **SCOPE** | Green | Function entry/exit boundaries |
### Step 5: Filter and Search Logs
Lusan provides multiple filtering mechanisms to isolate relevant log entries.
#### Scope-Level Filtering (Source Side)
Change logging priorities at the source application level, affecting which logs are generated and sent to `logcollector`.
**How to Use**:
1. Open **Live Logs** navigation pane
2. Expand application node to view scopes
3. Right-click scope → **Change Priority**
4. Select new priority level or disable scope
5. Changes take effect immediately
**Benefits**:
- Reduces network traffic by filtering at source
- Decreases `logcollector` load
- Improves application performance by skipping log generation
#### Message-Level Filtering (Viewer Side)
Filter already received logs in the log viewer. This filtering is performed on the Lusan side—logs of unselected priorities are hidden from view but remain in the buffer.
**Supported Filtering Criteria**:
| Filter Type | Description |
|-------------|-------------|
| **Priority Level** | Show only messages of selected priority levels (DEBUG, INFO, WARN, ERROR, FATAL, SCOPE) |
| **Duration** | Show only messages with duration ≥ specified value (for scope entry/exit timing) |
| **Source** | Show only messages from specified application name |
| **Source ID** | Show only messages from specified process ID |
| **Thread** | Show only messages from specified thread name |
| **Thread ID** | Show only messages from specified thread ID |
| **Text Phrase** | Show only messages containing specified text (supports wildcards: `*`, `?`) |
**Applying Filters**:
- Click arrow on column header
- Select filter criteria
- Multiple filters can be applied simultaneously
- Clear filters to show all messages
#### Filtering in Output Log Analyzer Window
Advanced filtering by selecting and analyzing specific scope sessions.
**How to Use**:
1. Double-click a log message in the main viewer
2. Log Analyzer Window opens at the bottom (tab: **Scope Analyzes**)
3. Select filtering mode using radio buttons
**Filtering Modes**:
- **Session Logs**: Show only messages from the selected scope session
- **Session Sublogs**: Show messages from selected session and all child scopes
- **Scope Logs**: Show all messages from the scope, regardless of session
- **Thread Logs**: Show all messages from the thread, regardless of scope
- **Process Logs**: Show all messages from the process, regardless of thread or scope
**Use Cases**:
- Trace execution flow through a single function call
- Analyze nested scope hierarchies
- Investigate thread-specific behavior
- Debug process-wide interactions
#### Filtering Best Practices
**Progressive Narrowing**:
1. Start with broad filters (e.g., filter by process)
2. Narrow down by thread
3. Further narrow by scope or text phrase
4. Use scope analyzer for detailed investigation
**Performance Optimization**:
- Use source-side filtering for high-volume logs
- Combine multiple filters for precise investigation
- Clear filters periodically to avoid missing related events
### Step 6: Runtime Logging Control
Lusan enables dynamic control of logging behavior without restarting applications.
#### Dynamic Control Capabilities
**Enable/Disable Log Scopes**
- Turn specific component logging on or off
- Change logging priority levels in real time
- Reduce noise from verbose components
- Enable detailed logging for components under investigation
**Adjust Priority Levels**
- Increase verbosity: `INFO` → `DEBUG` → add `SCOPE`
- Reduce verbosity to minimize overhead
- Per-scope priority control
- Independent control for each application
**Application-Wide Settings**
- Enable/disable all logging for an application
- Bulk scope management
- Quick toggles for emergency situations
**Save Configuration**
- Save current `logcollector` connection settings (IP address and port)
- Save logging scope priorities for all applications
- Persisted configuration used on next application start
#### Saving Log Settings
**Steps**:
1. Configure desired scope priorities in the Live Logs navigation pane
2. Click **Save log settings** toolbar button
3. Lusan collects scope priority information from each application
4. Sends configuration change request to applications
5. Applications save configuration to `areg.init`
6. On next start, applications use saved priorities
**Configuration Persistence**:
- Scope priorities saved in `areg.init` file
- Settings persist across application restarts
- Can be version-controlled with project configuration
#### Logging Priority Behavior
> [!NOTE]
> Logs are generated if lower-level logging is enabled. For example:
> - Scope with `INFO` level generates: INFO, WARN, ERROR, FATAL
> - `SCOPE` priority is independent and must be enabled explicitly
> - Users can disable log priorities while keeping `SCOPE` enabled
> - If `SCOPE` is not enabled, no entry/exit messages are generated
**Priority Levels (Ascending Order)**:
1. **DEBUG** (lowest) - Generates: DEBUG, INFO, WARN, ERROR, FATAL
2. **INFO** - Generates: INFO, WARN, ERROR, FATAL
3. **WARN** - Generates: WARN, ERROR, FATAL
4. **ERROR** - Generates: ERROR, FATAL
5. **FATAL** (highest) - Generates: FATAL only
6. **SCOPE** (independent) - Generates: Enter/Exit scope messages
7. **NOTSET** - Disables logging for the scope
#### Benefits of Runtime Control
- **No Downtime**: Adjust logging without service interruption
- **Performance Optimization**: Disable verbose logging in production
- **Targeted Debugging**: Enable detailed logs only where needed
- **Production Diagnostics**: Safely investigate issues in live systems
#### Best Practices
**Production Environments**:
- Keep default logging at `INFO` or `WARN` level
- Disable `SCOPE` logging by default (reduces overhead)
- Enable `DEBUG` and `SCOPE` only when actively investigating
- Disable verbose logging after capturing necessary information
**Development Environments**:
- Use `DEBUG | SCOPE` for active development
- Reduce verbosity in stable components
- Document scope purposes for effective filtering
**Performance-Critical Systems**:
- Minimize logging in hot paths
- Use fire-and-forget logging patterns
- Monitor `logcollector` resource usage
---
## Troubleshooting Live Logging
### Logs Not Appearing
#### Check Log Collector Status
Verify `logcollector` is running.
**Linux**:
```bash
ps aux | grep logcollector
```
**Windows**:
```powershell
tasklist | findstr logcollector
```
If not running, start `logcollector` as described in [Step 1](#step-1-launch-the-log-collector-service).
#### Verify Network Connectivity
Test connection to `logcollector` service port:
```bash
# Using telnet
telnet 127.0.0.1 8282
# Using netcat
nc -zv 127.0.0.1 8282
# Using curl (if HTTP endpoint available)
curl http://127.0.0.1:8282
```
**Expected Result**: Connection successful or port responding.
#### Confirm Application Configuration
**Check `areg.init` for applications and `logcollector`**:
- File exists and is readable: `./config/areg.init`
- Logging is enabled: `log::*::enable = true`
- Remote logging is enabled: `log::*::enable::remote = true`
- Service address matches `logcollector` host
- Port number matches `logcollector` configuration
**Check `lusan.init` for Lusan**:
- File exists and is readable: `./config/lusan.init`
- Logger service configuration matches `logcollector`
#### Verify Scope Priorities
Check that application scopes have logging enabled:
```text
log::*::scope::* = DEBUG | SCOPE # Enable all scopes
```
If scopes are set to `NOTSET`, no logs will be generated.
### Performance Issues
#### High Log Volume
**Symptoms**: Lusan lag, high CPU usage, memory consumption
**Solutions**:
- Increase filter specificity to reduce displayed logs
- Disable unnecessary scopes at source
- Reduce priority verbosity (INFO instead of DEBUG)
- Use offline analysis for intensive logging scenarios
- Clear log buffer periodically
#### Network Latency
**Symptoms**: Delayed log appearance, connection timeouts
**Solutions**:
- Ensure `logcollector` runs on the same network segment
- Check for network congestion or bandwidth issues
- Consider local `logcollector` instances for remote sites
- Use wired connections instead of wireless for critical systems
#### Memory Consumption
**Symptoms**: Lusan or `logcollector` consuming excessive memory
**Solutions**:
- Enable log rotation in `logcollector`
- Clear old logs from Lusan buffer
- Reduce log retention time
- Increase system RAM if log volume is legitimately high
### Connection Drops
**Symptoms**: Intermittent log gaps, disconnection messages, connection lost errors
#### Check Network Stability
- Verify network connection between Lusan and `logcollector` is stable
- Check for intermittent network issues
- Review router/switch logs for errors
#### Verify Log Collector Resources
- Check `logcollector` CPU usage (should be < 50%)
- Check `logcollector` memory usage
- Review `logcollector` logs for errors or warnings
- Ensure `logcollector` service has not crashed
#### Review Firewall Rules
- Verify firewall allows TCP port 8282 (or configured port)
- Check network policies don't block connections
- Temporarily disable firewall to test (development only)
#### Log Collector Crash
If `logcollector` has crashed:
1. Review crash logs or core dumps
2. Check system resource limits (ulimit on Linux)
3. Verify sufficient disk space for log files
4. Restart `logcollector` service
---
## Performance Considerations
### System Impact
#### Lusan Client
**Resource Usage**:
- **CPU**: Minimal during normal operation (< 5%)
- **Memory**: Scales with log volume and buffer size (typically 100-500 MB)
- **Network**: Depends on log volume (typical: 1-10 Mbps)
**Best Practices**:
- Use filtering to reduce processed log volume
- Clear old logs periodically during long sessions
- Close unused live log connections
- Monitor Lusan resource usage on constrained systems
#### Log Collector
**Resource Usage**:
- **CPU**: Scales with number of connected applications and log volume
- **Memory**: Buffering and log storage (typical: 200 MB - 2 GB)
- **Network**: Aggregate of all application log streams
- **Disk I/O**: If saving logs to disk
**Optimization**:
- Run `logcollector` on dedicated hardware for large deployments
- Use SSD storage for log files
- Configure log rotation to manage disk space
- Monitor resource usage with system tools
### Production Environments
#### Recommended Settings
**Default Logging Levels**:
- Production: `log::*::scope::* = INFO` (without SCOPE)
- Staging: `log::*::scope::* = INFO | SCOPE`
- Development: `log::*::scope::* = DEBUG | SCOPE`
**Scope Enablement**:
- Enable `DEBUG` and `SCOPE` selectively and temporarily
- Monitor impact on application performance
- Disable verbose logging after investigation
**Infrastructure**:
- Dedicated logging infrastructure for high-volume systems
- Monitor `logcollector` resource usage continuously
- Set up alerts for connection issues or resource exhaustion
- Plan for log storage capacity (estimate 10-100 MB/hour per application)
#### Performance Monitoring
**Key Metrics**:
- Log message rate (messages/second)
- Network bandwidth usage
- `logcollector` CPU and memory usage
- Application performance impact (compare with logging disabled)
**Alerting**:
- Set alerts for high message rates
- Monitor connection drops
- Alert on `logcollector` resource exhaustion
---
## Summary
Lusan's live log viewer transforms distributed logging from a challenge into a powerful development and debugging tool. By centralizing logs, providing real-time visibility, and enabling dynamic control, Lusan significantly reduces the time required to understand and diagnose issues in complex Areg-based systems.
### Key Capabilities
- ✅ **Centralized View**: All distributed logs in a single interface
- ✅ **Real-Time Monitoring**: Minimal latency (< 100ms typical)
- ✅ **Powerful Filtering**: Multiple criteria, scope analysis, text search
- ✅ **Runtime Control**: Adjust logging without application restarts
- ✅ **Dual Format Logging**: SQLite database and plain text
### Essential Tool For
- Distributed system development and debugging
- Multi-threaded application analysis
- Production troubleshooting and diagnostics
- System integration testing
- Performance optimization
### Next Steps
- **Explore Offline Analysis**: [Lusan Offline Log Analysis](./06g-lusan-offline-logging.md) for post-mortem debugging
- **Configure Log Collector**: [Log Collector Service Setup](./04d-logcollector.md) for production deployment
- **Optimize Configuration**: [Key-Value Data Persistence](./03b-key-value-persistence.md) for advanced settings
---
## Why Use Offline Log Analysis
Offline log analysis provides capabilities that are difficult or impossible to achieve with live logging alone.
### Reproducibility
Recorded logs capture the exact sequence of events, enabling:
- Repeated analysis from different perspectives
- Correlation discovery over multiple review sessions
- Validation of fix effectiveness against the original issue
### Collaboration
Share log files across teams:
- Remote team members can analyze issues independently
- Subject matter experts can review without system access
- Support teams can investigate customer issues safely
### No Runtime Dependencies
Analyze logs anywhere:
- No need for running applications
- No `logcollector` service required
- Works offline or in isolated environments
- Reduces system load during analysis
### Historical Analysis
Maintain forensic capabilities:
- Compare behavior across different time periods
- Identify regression patterns
- Track performance trends
- Meet compliance and audit requirements
---
## Prerequisites
### Required Components
| Component | Requirement | Notes |
|-----------|-------------|-------|
| **Lusan** | Built from [areg-sdk-tools](https://github.com/aregtech/areg-sdk-tools) | Main offline analysis tool |
| **Recorded Log Files** | `.sqlog` or `.log` format | Generated by `logcollector`, `logobserver`, or Lusan |
> [!NOTE]
> Unlike live logging, offline analysis requires no network connectivity, running services, or active applications. The `./config/lusan.init` file is optional but required if you switch to live logging. Lusan still depends on the Areg Framework for log parsing and visualization.
---
## Recording Logs for Offline Analysis
Before you can perform offline analysis, logs must be recorded during runtime.
### Method 1: Using `logcollector`
Configure `logcollector` to save logs to files or database. The `./config/areg.init` file should contain the following configuration:
```text
log::*::enable = true # Global logging enable/disable flag
log::*::enable::remote = true # Remote logging enable/disable flag
log::logcollector::enable::db = true # Log Collector: enable database output
log::logcollector::db::engine = sqlite3 # Log Collector: database engine
log::logcollector::db::name = log_%time%.sqlog # Log Collector: database name
log::logcollector::db::location = ./logs # Log Collector: database location
```
**Benefits:**
- Automatic recording of all aggregated logs
- Structured storage in database format
- No application code changes required
- Centralized log collection point
### Method 2: Using `logobserver`
Record logs using the `logobserver` console tool. The `./config/areg.init` file should contain the following configuration:
```text
log::*::enable = true # Global logging enable/disable flag
log::*::enable::remote = true # Remote logging enable/disable flag
log::logobserver::enable::db = true # Logobserver: enable database output
log::logobserver::db::engine = sqlite3 # Logobserver: database engine
log::logobserver::db::name = log_%time%.sqlog # Logobserver: database name
log::logobserver::db::location = ./logs # Logobserver: database location
```
**Benefits:**
- Selective recording of specific sessions
- Lightweight and flexible
- Command-line scriptable
- Works with existing `logcollector` setup
> [!TIP]
> More details about the `logobserver` console application, configuration, and command-line options can be found in the [Log Observer Documentation](./04c-logobserver.md).
### Method 3: Using Lusan GUI
Record directly from Lusan's live view:
**Steps:**
1. Start the Lusan application
2. Select one of the following options:
- In the menu, select **File → New Live Logs**
- Click the **New Live Logs** toolbar button
- Switch to the **Live Logs** tab in the Navigation pane and click **Connect to Log Collector**
3. Lusan automatically connects using settings from `./config/lusan.init`
4. Once connected to `logcollector`, Lusan records logs in real-time to a `.sqlog` file
**Benefits:**
- Visual confirmation of recorded data
- Pause, resume, and manage recordings
- Collection of scopes and priorities of interest
- User-friendly interface
**Recorded Log Formats:**
- **`.sqlog`**: SQLite3 database format (recommended for Lusan offline analysis)
- **`.log`**: Plain text format (can be opened with any text editor)
> [!TIP]
> Use SQLite3 database format (`.sqlog`) for primary storage to enable full-featured analysis with Lusan's offline log viewer.
---
## Step-by-Step Guide to Offline Log Analysis
### Step 1: Open Recorded Log Files
Launch Lusan and load previously recorded log files.
**Opening Methods:**
**Method 1: File Menu**
1. Launch Lusan
2. Navigate to **File → Open Offline Logs**
3. Browse to the location of recorded log files
4. Select one or more `.sqlog` or `.log` files
5. Click **Open**
**Method 2: Drag and Drop**
1. Launch Lusan
2. Drag log files from file manager
3. Drop onto Lusan window
4. Files open automatically in offline mode
**Method 3: Workspace Navigation**
1. Configure workspace log directory (see [Setup and Using Lusan](./06d-setup-lusan.md))
2. Browse to log directory in workspace navigation pane
3. Double-click a log file to open
**Multi-File Support:**
- Open multiple log files simultaneously
- Each file opens in a separate tab
- Compare logs from different sessions or time periods
- Switch between files using tab bar
### Step 2: Navigate the Log Session
Once a log file is opened, navigate through the recorded session using Lusan's navigation features.
**Navigation Controls:**
**Timeline Navigation**
- Scroll through logs chronologically
- Jump to specific timestamps
- Bookmark important events
- Navigate to first/last log entry
**Scope Tree Navigation**
The scope tree on the left displays the hierarchical structure of logging scopes from the recorded session:
- **Expand/Collapse**: Navigate scope hierarchy
- **Scope Selection**: Click to highlight logs from specific scope
- **Priority Indicators**: Visual indication of enabled priority levels
**Log Entry Details**
Each log entry displays:
- **Timestamp**: Date and time of log generation
- **Priority**: DEBUG, INFO, WARN, ERROR, FATAL, or SCOPE
- **Source**: Application (process) name and ID
- **Thread**: Thread name and ID
- **Scope**: Logging scope (function/component identifier)
- **Message**: Log message text
- **Duration**: Execution time (for scope entry/exit pairs)
### Step 3: Apply Filters and Search
Lusan provides multiple filtering mechanisms to isolate relevant log entries in offline mode.
#### 1. Scope-Level Filtering
Filter logs by selecting or deselecting scope nodes in the scope tree.
You can select/deselect scope-based priority levels to show or hide logs. The display is independent of priority level hierarchy.
**Example:**
- If `DEBUG` level of a scope node is selected
- But `WARN` and `INFO` levels are not selected
- Only `DEBUG` level logs of that scope are shown
- `WARN` and `INFO` logs are hidden
This allows filtering of particular components, even specific methods.
#### 2. Message-Level Filtering
Filter by message priority level in the log message window, functioning the same as in live logging. This filtering is performed on the Lusan side—logs of unselected priorities are hidden from the log viewer.
Multiple filtering criteria can be selected simultaneously. Click the arrow on the column header to apply filters.
**Currently Supported Filtering Criteria:**
| Filter Type | Description |
|-------------|-------------|
| **Priority Level** | Show only messages of selected priority levels (DEBUG, INFO, WARN, ERROR, FATAL, SCOPE) |
| **Duration** | Show only messages with duration ≥ specified value (for scope timing analysis) |
| **Source** | Show only messages from specified application name |
| **Source ID** | Show only messages from specified process ID |
| **Thread** | Show only messages from specified thread name |
| **Thread ID** | Show only messages from specified thread ID |
| **Text Phrase** | Show only messages containing specified text (supports wildcards: `*`, `?`) |
#### 3. Filtering in Output Log Analyzer Window
Filtering in the output **Log Analyzer** window works the same way as in live logging. Double-click on a message to select logs of the scope and session you want to analyze. This marks messages from the session of the selected scope and displays them in the Output Log Analyzer Window at the bottom of the application.
Use the following radio buttons to display filtered log messages:
- **Session Logs**: Show only messages of the selected scope session
- **Session Sublogs**: Show messages of the selected scope session and all its child scopes
- **Scope Logs**: Show all messages of the selected scope, regardless of session
- **Thread Logs**: Show all messages of the selected thread, regardless of scope and session
- **Process Logs**: Show all messages of the selected process, regardless of thread, scope, and session
**Filtering Best Practices:**
- Start with broad filters
- Narrow down progressively
- Combine multiple filters for precise investigation
---
## Advanced Offline Analysis Features
### Session Comparison
Compare logs from different time periods:
- Before vs. after a deployment
- Good run vs. failed run
- Different configuration scenarios
- Performance baseline vs. degraded state
**Workflow:**
1. Open multiple log files in separate tabs
2. Apply same filters to each session
3. Compare timing, behavior, and outcomes
4. Identify differences and anomalies
### Timing Analysis
Measure execution durations:
- Method execution times
- Request processing latency
- Component response times
- Scope entry/exit duration
**Use Cases:**
- Identify slow operations
- Measure performance improvements
- Detect timing regressions
- Optimize critical paths
### Bottleneck Identification
Find performance issues:
- Slowest operations in the execution flow
- Resource wait times
- Network latency spikes
- Thread synchronization delays
**Approach:**
1. Sort logs by duration column
2. Identify scopes with longest execution times
3. Analyze scope hierarchy for nested bottlenecks
4. Correlate with system resource logs if available
### Advanced Queries
Use SQL query language for complex searches directly in the SQLite database for advanced analysis and custom reporting.
**Example Use Cases:**
- Statistical analysis of log patterns
- Custom aggregations and summaries
- Complex correlation queries
- Export to external tools for visualization
**Accessing SQLite Database:**
```bash
# Open log file with SQLite command-line tool
sqlite3 log_2026-01-27.sqlog
# Example query: Find all ERROR logs from specific thread
SELECT timestamp, source, thread, scope, message
FROM logs
WHERE priority = 'ERROR' AND thread = 'WorkerThread'
ORDER BY timestamp;
```
---
## Use Cases for Offline Analysis
Offline analysis is ideal for:
**Post-Mortem Debugging**
Investigate production incidents after they occur without system access or disruption.
**Root Cause Analysis**
Deep-dive into complex issues without time pressure or live system constraints.
**Reviewing Logs from Customer Environments**
Analyze issues reported by customers using logs they provide.
**Training and Documentation**
Use real-world logs for educational purposes and creating troubleshooting guides.
**Sharing Logs with Distributed Teams**
Collaborate across time zones and locations by sharing log files.
**Compliance and Auditing**
Maintain historical records for regulatory requirements and audit trails.
**Performance Benchmarking**
Compare system behavior across versions, configurations, or deployment environments.
**Regression Analysis**
Identify when and where performance or functionality degraded over time.
---
## Best Practices for Offline Logging
### Recording Strategy
**Capture Important Events**
- Always record logs for complex or intermittent issues
- Enable appropriate priority levels before reproduction
- Include sufficient context (DEBUG + SCOPE for detailed analysis)
**Naming Conventions**
- Store log files with clear timestamps and context in filenames
- Use descriptive naming: `production_failure_2026-01-15.sqlog`
- Include environment, version, or issue ID in filename
- Example: `staging_v1.2.3_timeout_issue_2026-01-27.sqlog`
**Log Rotation**
- Configure automatic log rotation to manage disk space
- Set retention policies based on importance
- Archive critical logs before rotation
### Storage Management
**Archiving**
- Archive important logs for long-term reference
- Use compression to save storage space (`.sqlog.gz`, `.log.gz`)
- Maintain separate archives for critical incidents
**Retention Policy**
- Define retention periods aligned with project requirements
- Keep recent logs readily accessible (e.g., last 30 days)
- Archive older logs to cold storage
- Delete or compress logs beyond retention period
**Backup Strategy**
- Back up critical incident logs to multiple locations
- Use version control for reproducible test logs
- Document log file locations and access procedures
### Analysis Workflow
**Collaborative Debugging**
- Share offline logs with team members for collaborative analysis
- Include reproduction steps and context with shared logs
- Document findings in issue tracking systems
**Fix Validation**
- Use offline analysis to validate fixes before redeploying
- Compare logs before and after fix implementation
- Verify issue no longer appears in new log sessions
**Documentation**
- Document findings and correlations discovered during analysis
- Create playbooks for common issue patterns identified in logs
- Update troubleshooting guides based on log analysis insights
### Performance Optimization
**Execution Measurement**
- Use per-method execution measurement in logs to find performance issues
- Identify slowest operations using duration sorting
- Focus optimization efforts on high-impact areas
**Bottleneck Detection**
- Track sequences of calls and parallel tasks to identify bottlenecks
- Analyze scope hierarchy for nested performance issues
- Correlate with system metrics when available
**Comparative Analysis**
- Find performance gaps by comparing execution times across different runs
- Identify regressions by comparing current vs. baseline logs
- Validate performance improvements with before/after log analysis
**Optimization Strategy**
- Optimize business logic to perform parallel computing based on log insights
- Identify opportunities for asynchronous processing
- Reduce unnecessary logging in performance-critical paths
---
## Comparison: Live Logging vs Offline Log Analysis
This table highlights when to use Live Log Viewer versus Offline Log Viewer in Lusan and how they complement each other.
| Aspect | Live Log Viewer | Offline Log Viewer |
|-------------------------------|------------------------------------------|-------------------------------------------|
| **Data Source** | Real-time logs from running applications | Previously recorded log files |
| **Requires Running Apps** | Yes | No |
| **Requires `logcollector`** | Yes | No |
| **Network Connectivity** | Required | Not required |
| **Runtime Overhead** | Yes (configurable) | None |
| **Best Suited For** | Active development and debugging | Post-mortem and deep investigation |
| **Incident Reproduction** | Limited | Full replay of recorded events |
| **Collaboration** | Requires shared environment | Shareable log files |
| **Performance Analysis** | Near real-time observation | Precise historical timing analysis |
| **Production Safety** | Medium (depends on verbosity) | High (read-only analysis) |
| **Log Scope Control** | Dynamic at runtime | Fixed to recorded configuration |
| **Multi-Session Comparison** | Limited | Native support |
| **SQL-Based Analysis** | No | Yes (SQLite `.sqlog`) |
### Recommended Usage Pattern
**Use Live Logging When:**
- Actively developing and debugging new features
- Performing system integration testing
- Monitoring applications in early testing phases
- Adjusting logging priorities on-the-fly
**Use Offline Log Analysis When:**
- Investigating production incidents
- Performing audit and compliance reviews
- Conducting regression analysis
- Sharing findings with distributed teams
**Combine Both Modes:**
- Capture logs live during critical operations
- Analyze them offline for deeper insights
- Use live mode for immediate feedback
- Use offline mode for thorough investigation
---
## Summary
Lusan's offline log viewer is an indispensable tool for thorough analysis of Areg-based distributed systems and multi-threaded applications. By enabling detailed examination of recorded sessions without runtime dependencies, it facilitates effective debugging, collaboration, and knowledge building across development teams. It is an essential tool for production diagnostics and long-term maintenance.
### Key Capabilities
- ✅ No runtime dependencies required
- ✅ Complete session replay and navigation
- ✅ Powerful filtering and correlation capabilities
- ✅ Support for multiple simultaneous log files
- ✅ Advanced query capabilities via SQLite database
- ✅ Flexible recording options (`logcollector`, `logobserver`, Lusan)
### Complementary to Live Logging
**Live Logging**: For active development and immediate feedback
**Offline Analysis**: For deep investigation, documentation, and collaboration
Together, live and offline logging provide a complete observability solution for distributed Areg applications.
---
## Issue 2: Network Resolution (DNS) Issues
### Symptoms
Network-related errors such as:
```plaintext
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease
Temporary failure resolving 'archive.ubuntu.com'
```
This often occurs due to DNS resolution errors in WSL.
### Diagnosing DNS Issues
Check the current DNS configuration:
```bash
cat /etc/resolv.conf
```
If the `nameserver` entry shows your router's IP address (e.g., `nameserver 172.23.112.1`) instead of a public DNS server, you need to update the configuration.
### Solution 1: Update DNS Settings in `/etc/resolv.conf`
**Method A: Using Text Editor**
1. Open the WSL terminal
2. Edit the DNS resolver configuration file:
```bash
sudo vim /etc/resolv.conf
```
3. Change the `nameserver` entry:
- Press `i` to enter insert mode
- Replace the existing IP with `8.8.8.8` (Google DNS)
- Alternative DNS: `1.1.1.1` (Cloudflare), `8.8.4.4` (Google secondary)
4. Save and close:
- Press `Esc`
- Type `:wq`
- Press `Enter`
**Method B: Using Command Line**
Set DNS directly with a single command:
```bash
sudo sh -c "echo nameserver 8.8.8.8 > /etc/resolv.conf"
```
**Verify DNS Resolution**
Test DNS resolution:
```bash
nslookup google.com
```
### Solution 2: Enable Automatic DNS Resolution
Configure WSL to automatically update DNS settings:
**Step 1: Check `/etc/wsl.conf`**
Edit the WSL configuration file:
```bash
sudo vim /etc/wsl.conf
```
Add or update the `[network]` section:
```ini
[network]
generateResolvConf = true
```
**Step 2: Restart WSL**
Restart the WSL service:
```bash
# In PowerShell (Windows)
wsl --shutdown
# Wait a few seconds, then start WSL again
wsl
```
### Solution 3: Reset WSL Network Configuration
If DNS issues persist, reset the network configuration:
**Step 1: Reset Winsock**
Open PowerShell as administrator:
```powershell
netsh winsock reset
```
**Step 2: Restart Machine**
Restart your computer to apply changes.
**Step 3: Verify Resolution**
After restart, launch WSL and test DNS:
```bash
ping google.com
```
> [!TIP]
> These solutions should address most update and DNS-related issues encountered with WSL. If problems persist, consult the [official WSL documentation](https://learn.microsoft.com/en-us/windows/wsl/) or seek assistance from community forums.
---
## Issue 3: Configuring Communication Between Windows and WSL
### Background
When using Windows Subsystem for Linux (WSL) with Areg SDK, you may encounter communication issues between Windows and WSL services. By default, the [`areg.init`](./../../framework/areg/resources/areg.init) configuration file uses `localhost` for service endpoints, which works for services running on the same platform but not across Windows and WSL boundaries.
### Understanding WSL Networking
> [!IMPORTANT]
> **Key Networking Concepts:**
>
> - **Windows-to-WSL Connections**: Windows applications can connect to WSL services using `localhost` without additional configuration.
>
> - **WSL-to-Windows Connections**: WSL applications **cannot** connect to Windows services using `localhost` in the default NAT networking mode. You must use the Windows host IP address.
>
> - **WSL Networking Modes**:
> - **NAT Mode** (default): WSL uses Network Address Translation. Requires IP address configuration for WSL-to-Windows connections.
> - **Mirror Mode**: May allow `localhost` to work seamlessly between Windows and WSL (not fully tested).
>
> For more details, refer to the official documentation on **[Mirrored Mode Networking](https://learn.microsoft.com/en-us/windows/wsl/networking#mirrored-mode-networking)**. Networking modes can be configured in the `.wslconfig` file or via WSL Settings.
### Common Scenario
In the following examples, we configure communication for:
- **Message Router (`mtrouter`)**: Running on Windows
- **Log Collector (`logcollector`)**: Running on WSL
- **Applications**: Can run on either Windows or WSL
### Solution 1: Update All IP Addresses (Recommended)
This approach explicitly configures all service IP addresses, providing clear visibility and avoiding ambiguity.
#### Step 1: Identify IP Addresses
**Windows Host IP Address:**
Open PowerShell or Command Prompt:
```powershell
ipconfig
```
Look for the `Ethernet adapter vEthernet (WSL)` or `Wi-Fi` section and note the IPv4 Address.
**Example output:**
```
Ethernet adapter vEthernet (WSL):
IPv4 Address. . . . . . . . . . . : 172.23.96.1
```
**WSL IP Address:**
Open WSL terminal:
```bash
ip addr show eth0
```
Or use `ifconfig`:
```bash
ifconfig eth0
```
Look for the `inet` address.
**Example output:**
```
inet 172.23.99.47/20
```
Note both IP addresses for use in configuration.
#### Step 2: Update WSL Configuration
Edit `areg.init` for applications running on **WSL**:
```bash
sudo vim ./config/areg.init
```
Update the service addresses:
```ini
# Message Router (running on Windows)
router::*::address::tcpip = 172.23.96.1 # Windows host IP
# Log Collector (running on WSL)
logger::*::address::tcpip = 172.23.99.47 # WSL IP
```
Replace the example IPs with your actual addresses from Step 1.
#### Step 3: Update Windows Configuration
Edit `areg.init` for applications running on **Windows**:
```ini
# Message Router (running on Windows)
router::*::address::tcpip = 172.23.96.1 # Windows host IP
# Log Collector (running on WSL)
logger::*::address::tcpip = 172.23.99.47 # WSL IP
```
Use the same IP addresses as in the WSL configuration.
#### Step 4: Restart Services
Restart all services to apply changes:
**On Windows:**
```powershell
# Stop services
taskkill /IM mtrouter.exe /F
# Start services
.\mtrouter.exe
```
**On WSL:**
```bash
# Stop services
pkill -9 logcollector
# Start services
./logcollector &
```
#### Step 5: Verify Communication
**Test from WSL:**
```bash
# Test connection to Windows router
telnet 172.23.96.1 8181
```
**Test from Windows:**
```powershell
# Test connection to WSL log collector
telnet 172.23.99.47 8282
```
### Solution 2: Update Only Necessary IP Addresses
This approach minimizes configuration changes by leveraging the fact that Windows applications can access WSL services via `localhost`.
> [!NOTE]
> **Key Principle**: Only the Windows host IP address needs to be configured because:
> - Windows → WSL: `localhost` works automatically
> - WSL → Windows: Requires Windows host IP address
#### Step 1: Identify Windows IP Address
Open PowerShell or Command Prompt:
```powershell
ipconfig
```
Note the IPv4 Address for the `Ethernet adapter vEthernet (WSL)` or active network adapter.
**Example:**
```
IPv4 Address. . . . . . . . . . . : 172.23.96.1
```
#### Step 2: Update WSL Configuration
Edit `areg.init` for applications running on **WSL**:
```bash
sudo vim ./config/areg.init
```
Update only the router address:
```ini
# Message Router (running on Windows)
router::*::address::tcpip = 172.23.96.1 # Windows host IP
# Log Collector (running on WSL) - leave as localhost
logger::*::address::tcpip = localhost
```
#### Step 3: Update Windows Configuration
Edit `areg.init` for applications running on **Windows**:
```ini
# Message Router (running on Windows)
router::*::address::tcpip = 172.23.96.1 # Windows host IP
# Log Collector (running on WSL) - leave as localhost
logger::*::address::tcpip = localhost
```
#### Step 4: Restart Services
Restart services as described in Solution 1, Step 4.
### Important Configuration Rules
> [!IMPORTANT]
> **You cannot mix Solution 1 and Solution 2.**
>
> For each service (router, logger), you must use the **same configuration** in both Windows and WSL `areg.init` files:
>
> - **Consistent**: Both files use `localhost` for a service
> - **Consistent**: Both files use specific IP address for a service
> - **Inconsistent** (❌ **will fail**): One file uses `localhost`, the other uses IP address
>
> **Example of incorrect configuration:**
> ```ini
> # Windows areg.init
> logger::*::address::tcpip = localhost
>
> # WSL areg.init
> logger::*::address::tcpip = 172.23.99.47 # ❌ WILL NOT WORK
> ```
>
> For detailed explanation, see [this discussion](https://github.com/aregtech/areg-sdk/pull/480#issuecomment-2568508064).
### Troubleshooting Communication Issues
**Firewall Blocking Connections**
If connections fail, check Windows Firewall:
```powershell
# Allow specific port
netsh advfirewall firewall add rule name="Areg Router" dir=in action=allow protocol=TCP localport=8181
# Allow specific application
netsh advfirewall firewall add rule name="Areg Router" dir=in action=allow program="C:\path\to\mtrouter.exe"
```
**IP Address Changes**
WSL IP addresses may change after system restart. If connections fail:
1. Re-check IP addresses using `ipconfig` and `ip addr`
2. Update `areg.init` files if addresses changed
3. Restart services
**Verify Port Availability**
Check if ports are listening:
**Windows:**
```powershell
netstat -an | findstr 8181
```
**WSL:**
```bash
netstat -tuln | grep 8282
```
### Additional Resources
For further details on configuring network communication between Windows and WSL, refer to the official documentation:
- [Accessing Network Applications with WSL](https://learn.microsoft.com/en-us/windows/wsl/networking)
- [Advanced Settings Configuration in WSL](https://learn.microsoft.com/en-us/windows/wsl/wsl-config)
---
## Summary
This document covered three main categories of WSL issues:
1. **Update Errors**: Service initialization failures resolved by updating or reinstalling WSL
2. **DNS Issues**: Network resolution problems fixed by configuring DNS servers
3. **Windows-WSL Communication**: Cross-platform service connectivity configured via IP addresses
### Key Takeaways
- ✅ Always run WSL commands with administrator privileges when needed
- ✅ Test DNS resolution after configuration changes
- ✅ Use consistent IP address configuration across Windows and WSL
- ✅ Restart services after configuration changes
- ✅ Verify firewall rules allow required ports
For additional help, consult the [official WSL documentation](https://learn.microsoft.com/en-us/windows/wsl/) or community forums.