소스 검색

auto commit 2.1.18

lith 2 년 전
부모
커밋
78230a7a13
100개의 변경된 파일1540개의 추가작업 그리고 751개의 파일을 삭제
  1. 1 0
      .github/workflows/action-main.yml
  2. 3 0
      Doc/Vit.Core.md
  3. 8 8
      Publish/DevOps/build-bash/51.docker-deploy-copy.sh
  4. 5 5
      Publish/DevOps/github-bash/75.github-push-to-serset-release.sh
  5. 3 3
      Publish/DevOps/github-bash/76.github-push-release.sh
  6. 3 3
      Publish/DevOps/github-bash/startup.bash
  7. 14 3
      Publish/DevOps/jenkins-bash/release.jenkins.pipeline
  8. 1 12
      Publish/DevOps/jenkins-bash/startup.bash
  9. 2 6
      Publish/DevOps/release-bash/71.file-zip.sh
  10. 6 3
      Publish/DevOps/release-bash/73.docker-image-build-push.sh
  11. 1 3
      Publish/DevOps/release-bash/startup.bash
  12. 1 1
      dotnet/Gateway/App.Gateway/App.Gateway.csproj
  13. 2 2
      dotnet/Gateway/App.Gateway/appsettings.json
  14. 0 1
      dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Doc/Sers.CL.Ipc.NamedPipe-额外命名管道/Sers.CL.Ipc.NamedPipe.csproj
  15. 1 1
      dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Sers.CL.Ipc.NamedPipe.csproj
  16. 1 1
      dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.SharedMemory/Sers.CL.Ipc.SharedMemory.csproj
  17. 1 1
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Sers.CL.Socket.Iocp.csproj
  18. 1 1
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.ThreadWait/Sers.CL.Socket.ThreadWait.csproj
  19. 4 4
      dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/ProgramQps.cs
  20. 4 1
      dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/appsettings.json
  21. 7 1
      dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmServer/appsettings.json
  22. 22 0
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/DeliveryClient.cs
  23. 30 1
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/DeliveryServer.cs
  24. 2 1
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/OrganizeClientBuilder.cs
  25. 3 1
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/OrganizeServerBuilder.cs
  26. 1 1
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/Sers.CL.WebSocket.csproj
  27. 1 1
      dotnet/Library/Sers/Sers.CL/Zmq/FullDuplex/Sers.CL.Zmq.FullDuplex/Sers.CL.Zmq.FullDuplex.csproj
  28. 1 1
      dotnet/Library/Sers/Sers.CL/Zmq/ThreadWait/Sers.CL.ClrZmq.ThreadWait/Sers.CL.ClrZmq.ThreadWait.csproj
  29. 0 1
      dotnet/Library/Sers/Sers.Core/Sers.Core.Temp/Sers.Core.Temp.csproj
  30. 2 2
      dotnet/Library/Sers/Sers.Core/Sers.Core/CL/CommunicationManage/CommunicationManageClient.cs
  31. 2 2
      dotnet/Library/Sers/Sers.Core/Sers.Core/CL/CommunicationManage/CommunicationManageServer.cs
  32. 2 2
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Api/LocalApi/LocalApiService/LocalApiService.cs
  33. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Api/LocalApi/StaticFileTransmit/Extensions/ILocalApiService_StaticFileMap_Extensions.cs
  34. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiLoader/ApiLoaderMng.cs
  35. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/ApiTraceMng.cs
  36. 60 0
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/ElasticSearchCollector.appsettings.json
  37. 88 0
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/ElasticSearchCollector.cs
  38. 0 10
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/IApiTraceCollector.cs
  39. 7 5
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/SplunkCollector.appsettings.json
  40. 68 56
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/SplunkCollector.cs
  41. 6 138
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/TxtCollector.cs
  42. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/App/SersApplication.cs
  43. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Env/UsageReporter.cs
  44. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/Controller/SubscriberLoader.cs
  45. 8 8
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/EFrameType.cs
  46. 2 2
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/HotPlugSubscriber.cs
  47. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/MessageCenterService.cs
  48. 5 7
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/MessageClient.cs
  49. 6 6
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/SubscriberManage.cs
  50. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Rpc/RpcContextData.cs
  51. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Serialization/Text/Serialization_Text.cs
  52. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Sers.Core.csproj
  53. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/ApiLoader.cs
  54. 5 5
      dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/GatewayHelp.cs
  55. 1 1
      dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/RateLimit/RateLimitMng.cs
  56. 1 1
      dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/Sers.Gateway.csproj
  57. 1 1
      dotnet/Library/Sers/Sers.Hardware/Sers.Hardware/Sers.Hardware.csproj
  58. 1 1
      dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Extensions/ILocalApiService_LoadSerslotExtApi_Extensions.cs
  59. 1 1
      dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Extensions/IWebHostBuilder_UseSerslot_Extensions.cs
  60. 1 1
      dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Sers.Serslot.csproj
  61. 10 8
      dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/SerslotServer.cs
  62. 1 1
      dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/Sers.ServiceStation.csproj
  63. 9 4
      dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/ServiceStation.cs
  64. 4 2
      dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Module/LoggerTest.cs
  65. 2 2
      dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Module/SerializationTest.cs
  66. 0 27
      dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Util/ComponentModel/ExceptionTest.cs
  67. 1 1
      dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Util/ConfigurationManager/ConfigurationManagerTest.cs
  68. 34 7
      dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/appsettings.json
  69. 19 4
      dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/EnumExtensions.cs
  70. 1 1
      dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/ObjectExt/ObjectExtExtensions.cs
  71. 3 13
      dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/ObjectExtensions.cs
  72. 4 6
      dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/TypeExtensions.cs
  73. 26 5
      dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/byte/ByteDataExtensions.cs
  74. 134 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/Client/ElasticSearchClient.cs
  75. 57 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/Client/ElasticSearchRecord.cs
  76. 56 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/ElasticSearchCollector.cs
  77. 42 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/LogRecord.cs
  78. 130 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/Client/SplunkClient.cs
  79. 22 24
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/Client/SplunkRecord.cs
  80. 47 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/LogRecord.cs
  81. 0 59
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/SplunkClient.cs
  82. 20 66
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/SplunkCollector.cs
  83. 39 11
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Vit.Logger.appsettings.json
  84. 31 17
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogMng.Extensions.cs
  85. 1 1
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogMng.cs
  86. 36 33
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/Logger.cs
  87. 20 19
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Extensions/ObjectSerializeExtensions.cs
  88. 53 3
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/ISerialization.cs
  89. 166 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Json.cs
  90. 20 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Obsolete/Serialization.cs
  91. 0 12
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Serialization.cs
  92. 9 6
      dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Serialization_Newtonsoft.cs
  93. 34 43
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/ApiReturn.cs
  94. 36 19
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/Exception_Extensions.cs
  95. 0 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError.Const.cs
  96. 18 18
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError.cs
  97. 36 0
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError_Extensions.cs
  98. 4 4
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/PageData.cs
  99. 4 4
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/PageInfo.cs
  100. 4 4
      dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/SortItem.cs

+ 1 - 0
.github/workflows/action-main.yml

@@ -32,6 +32,7 @@ jobs:
         run: |
            set -e
            echo start build
+           export APPNAME="Sers"
            export DOCKER_USERNAME="${{ secrets.DOCKER_USERNAME  }}"
            export DOCKER_PASSWORD="${{ secrets.DOCKER_PASSWORD }}"
            export NUGET_SERVER="${{ secrets.NUGET_SERVER  }}"

+ 3 - 0
Doc/Vit.Core.md

@@ -0,0 +1,3 @@
+log to txt/console/splunk/ElasticSearch(Vit.Core.Module.Log.Logger),
+Serialize(Vit.Core.Module.Serialization.Json),
+ConfigurationManager(Vit.Core.Util.ConfigurationManager.Appsettings.json),

+ 8 - 8
Publish/DevOps/build-bash/51.docker-deploy-copy.sh

@@ -13,25 +13,25 @@ export basePath=/root/temp/svn
 #---------------------------------------------------------------------
 #(x.2)
 publishPath="$basePath/Publish/release/release/Station(net5.0)"
-dockerPath=$basePath/Publish/release/release/docker-deploy
+deployPath=$basePath/Publish/release/release/docker-deploy
 
 
 
 #----------------------------------------------
 echo "(x.3)copy dir"
-\cp -rf "$basePath/Publish/ReleaseFile/docker-deploy/." "$dockerPath"
+\cp -rf "$basePath/Publish/ReleaseFile/docker-deploy/." "$deployPath"
 
 
 
 #---------------------------------------------------------------------
 echo "(x.4)copy station"
 
-\cp -rf "$publishPath/ServiceCenter/appsettings.json" "$dockerPath/sers"
-\cp -rf "$publishPath/Gateway/appsettings.json" "$dockerPath/sers-gateway"
-\cp -rf "$publishPath/Gover/appsettings.json" "$dockerPath/sers-gover"
-\cp -rf "$publishPath/Demo/appsettings.json" "$dockerPath/sers-demo"
-\cp -rf "$publishPath/Robot/appsettings.json" "$dockerPath/sers-demo-robot"
-\cp -rf "$basePath/Publish/release/release/StressTest/单体压测net5.0/ServiceCenter/appsettings.json" "$dockerPath/sers-demo-sersall"
+\cp -rf "$publishPath/ServiceCenter/appsettings.json" "$deployPath/sers"
+\cp -rf "$publishPath/Gateway/appsettings.json" "$deployPath/sers-gateway"
+\cp -rf "$publishPath/Gover/appsettings.json" "$deployPath/sers-gover"
+\cp -rf "$publishPath/Demo/appsettings.json" "$deployPath/sers-demo"
+\cp -rf "$publishPath/Robot/appsettings.json" "$deployPath/sers-demo-robot"
+\cp -rf "$basePath/Publish/release/release/StressTest/单体压测net5.0/ServiceCenter/appsettings.json" "$deployPath/sers-demo-sersall"
  
 
 

+ 5 - 5
Publish/DevOps/github-bash/75.github-push-to-serset-release.sh

@@ -9,9 +9,9 @@ export basePath=/root/temp/svn
 
 export version=`grep '<Version>' $(grep '<pack>\|<publish>' ${basePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
 
-export name=ServiceAdaptor
+export APPNAME=xxxxxx
 
-export export GIT_SSH_SECRET=xxxxxx
+export GIT_SSH_SECRET=xxxxxx
 
 # "
 
@@ -39,9 +39,9 @@ git config --global user.name 'lith'
 mkdir -p /root/code
 cd /root/code
 git clone git@github.com:serset/release.git /root/code
-mkdir -p /root/code/file/${name}/${name}-${version}
-\\cp -rf  /root/release/release-zip/. /root/code/file/${name}/${name}-${version}
-git add /root/code/file/${name}/${name}-${version}/.
+mkdir -p /root/code/file/${APPNAME}/${APPNAME}-${version}
+\\cp -rf  /root/release/release-zip/. /root/code/file/${APPNAME}/${APPNAME}-${version}
+git add /root/code/file/${APPNAME}/${APPNAME}-${version}/.
 git commit -m 'auto commit ${version}'
 git push -u origin master \" "
 

+ 3 - 3
Publish/DevOps/github-bash/76.github-push-release.sh

@@ -9,7 +9,7 @@ export basePath=/root/temp/svn
 
 export version=`grep '<Version>' $(grep '<pack>\|<publish>' ${basePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
 
-export name=ServiceAdaptor
+export APPNAME=xxxxxx
 
 # "
 
@@ -23,7 +23,7 @@ export name=ServiceAdaptor
 
 
 
-echo "release_name=${name}-${version}" >> $GITHUB_ENV
+echo "release_name=${APPNAME}-${version}" >> $GITHUB_ENV
 echo "release_tag=${version}" >> $GITHUB_ENV
 
 echo "release_draft=false" >> $GITHUB_ENV
@@ -38,7 +38,7 @@ echo "release_version=${version}" >> $GITHUB_ENV
 #filePath=$basePath/Publish/release/release-zip/Sers-ServiceCenter(net5.0)-${version}.zip
 #fileType="${filePath##*.}"
 #echo "release_assetPath=${filePath}" >> $GITHUB_ENV
-#echo "release_assetName=${name}-${version}.${fileType}" >> $GITHUB_ENV
+#echo "release_assetName=${APPNAME}-${version}.${fileType}" >> $GITHUB_ENV
 #echo "release_contentType=application/zip" >> $GITHUB_ENV
 
 

+ 3 - 3
Publish/DevOps/github-bash/startup.bash

@@ -6,18 +6,18 @@ set -e
 #(x.1)参数
 args_="
 
+export APPNAME=xxxxxx
+
 export DOCKER_USERNAME=serset
 export DOCKER_PASSWORD=xxxxxx
 
 export NUGET_SERVER=https://api.nuget.org/v3/index.json
 export NUGET_KEY=xxxxxx
 
-export export GIT_SSH_SECRET=xxxxxx
+export GIT_SSH_SECRET=xxxxxx
 
 # "
 
-export name=Sers
-
 #----------------------------------------------
 #(x.2)当前路径
 curPath=$PWD

+ 14 - 3
Publish/DevOps/jenkins-bash/release.jenkins.pipeline

@@ -3,6 +3,7 @@ pipeline {
 
     environment {
         basePath = "/root/docker-data/dev/jenkins/jenkins_home/workspace/Repo/Sers/code"
+        APPNAME = "Sers"
         SVN_USERNAME = "jenkins"
         SVN_PASSWORD = "xxxxxx"
         DOCKER_USERNAME = "serset"
@@ -12,24 +13,34 @@ pipeline {
         NUGET_PATH = "/root/docker-data/dev/jenkins/jenkins_home/workspace/.nuget"
     }
     stages {
+        stage('(x.0)confirm') { 
+            agent any 
+            steps {
+                timeout(10) {
+                    script { 
+                        inputData = input message: "Are you sure to build and release?", ok: 'Proceed?', parameters: [string(defaultValue: '', description: 'text comment', name: 'comment')], submitterParameter: 'APPROVER' 
+                    } 
+                }
+            } 
+        }
         stage('(x.1)svn-update') { 
             agent any 
             steps {
-                sh "chroot /host bash -c 'set -e; export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/jenkins-bash;bash 01.svn-update.sh;  '"
+                sh "chroot /host bash -c 'set -e; export APPNAME=$APPNAME;export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/jenkins-bash;bash 01.svn-update.sh;  '"
             } 
         }
 
         stage('(x.4)build') {
             agent any 
             steps {
-                sh "chroot /host bash -c 'set -e; export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/build-bash; bash startup.bash;  '"
+                sh "chroot /host bash -c 'set -e; export APPNAME=$APPNAME;export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/build-bash; bash startup.bash;  '"
             } 
         }
 
         stage('(x.5)release-bash') { 
             agent any 
             steps {
-                sh "chroot /host bash -c 'set -e; export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/release-bash; bash startup.bash;  '"
+                sh "chroot /host bash -c 'set -e; export APPNAME=$APPNAME;export SVN_USERNAME=$SVN_USERNAME;export SVN_PASSWORD=$SVN_PASSWORD;export DOCKER_USERNAME=$DOCKER_USERNAME;export DOCKER_PASSWORD=$DOCKER_PASSWORD;export NUGET_KEY=$NUGET_KEY;export NUGET_SERVER=$NUGET_SERVER;export NUGET_PATH=$NUGET_PATH;    cd $basePath/Publish/DevOps/release-bash; bash startup.bash;  '"
             } 
         }
     } 

+ 1 - 12
Publish/DevOps/jenkins-bash/startup.bash

@@ -3,19 +3,10 @@ set -e
 
 # cd /root/docker-data/dev/jenkins/jenkins_home/workspace/Repo/Sers/code/Publish/DevOps/jenkins-bash; bash startup.bash;
 
-#chroot /host bash -c "set -e; \
-#export SVN_USERNAME=jenkins; \
-#export SVN_PASSWORD=xxxxxx; \
-#export DOCKER_USERNAME=serset; \
-#export DOCKER_PASSWORD=xxxxxx; \
-#export NUGET_KEY=xxxxxx; \
-#export NUGET_SERVER=https://api.nuget.org/v3/index.json; \
-#export NUGET_PATH=/root/docker-data/dev/jenkins/jenkins_home/workspace/.nuget; \
-#cd /root/docker-data/dev/jenkins/jenkins_home/workspace/Repo/Sers/code/Publish/DevOps/jenkins-bash; bash startup.bash; "
-
 #---------------------------------------------------------------------
 #(x.1)²ÎÊý
 args_="
+export APPNAME=xxxxxx
 
 export SVN_USERNAME=jenkins
 export SVN_PASSWORD=xxxxxx
@@ -30,8 +21,6 @@ export NUGET_PATH=/root/docker-data/dev/jenkins/jenkins_home/workspace/.nuget
 
 # "
 
-export name=Sers
-
 #----------------------------------------------
 #(x.2)µ±Ç°Â·¾¶ 
 curPath=$PWD

+ 2 - 6
Publish/DevOps/release-bash/71.file-zip.sh

@@ -9,14 +9,10 @@ export basePath=/root/temp/svn
 
 export version=`grep '<Version>' $(grep '<pack>\|<publish>' ${basePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
 
-export name=Sers
+export APPNAME=xxxxxx
 
 # "
 
- 
-
-
-
 #----------------------------------------------
 echo "压缩文件"
 
@@ -31,7 +27,7 @@ for dirname in \`ls /root/code/Publish/release/release\`
 do
   if [ -d \$releasePath/release/\$dirname ]
   then
-    filezip zip -p -i \$releasePath/release/\$dirname -o \$releasePath/release-zip/${name}-\${dirname}-${version}.zip 
+    filezip zip -p -i \$releasePath/release/\$dirname -o \$releasePath/release-zip/${APPNAME}-\${dirname}-${version}.zip 
   fi
 done
 

+ 6 - 3
Publish/DevOps/release-bash/73.docker-image-build-push.sh

@@ -55,9 +55,12 @@ dockerPath=$basePath/Publish/release/release/docker-image
 for dockerName in `ls $dockerPath`
 do
   if [ -d $dockerPath/$dockerName ]
-  then 
-    echo "docker build $dockerName"
-    docker buildx build $dockerPath/$dockerName -t $DOCKER_USERNAME/$dockerName:$version -t $DOCKER_USERNAME/$dockerName --platform=linux/amd64,linux/arm64,linux/arm/v7 --push
+  then
+    platform="linux/amd64,linux/arm64,linux/arm/v7"
+    if [ -f "$dockerPath/$dockerName/Dockerfile.platform" ]; then platform=`cat "$dockerPath/$dockerName/Dockerfile.platform"`; fi
+
+    echo "docker build $dockerName, platform: $platform"
+    docker buildx build $dockerPath/$dockerName -t $DOCKER_USERNAME/$dockerName:$version -t $DOCKER_USERNAME/$dockerName --platform=$platform --push
   fi
 done
 

+ 1 - 3
Publish/DevOps/release-bash/startup.bash

@@ -6,15 +6,13 @@ set -e
 #(x.1)参数
 args_="
 
-
-export name=Sers
+export APPNAME=xxxxxx
 
 export DOCKER_USERNAME=serset
 export DOCKER_PASSWORD=xxx
 
 export NUGET_SERVER=https://api.nuget.org/v3/index.json
 export NUGET_KEY=xxxxxxxxxx
-
 # "
 
 

+ 1 - 1
dotnet/Gateway/App.Gateway/App.Gateway.csproj

@@ -8,7 +8,7 @@
 	<PropertyGroup>
 		<OutputType>Exe</OutputType>
 		<TargetFramework>net5.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 		<PackageProjectUrl>https://github.com/serset/Sers</PackageProjectUrl>
 	</PropertyGroup>
 

+ 2 - 2
dotnet/Gateway/App.Gateway/appsettings.json

@@ -84,10 +84,10 @@
         /* url,可多个 */
         "urls": [ "http://*:4582" ],
 
-        /* https证书配置,可不指定。若urls中指定了https协议,请在此指定对应的https证书 */
+        /* ssl证书,可不指定。若urls中指定了https协议,请在此指定对应的https证书 */
         "//certificates": [
           {
-            "filePath": "data/serset-com-iis-0923120142.pfx",
+            "filePath": "Data/ssl.pfx",
             "password": "password"
           }
         ],

+ 0 - 1
dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Doc/Sers.CL.Ipc.NamedPipe-额外命名管道/Sers.CL.Ipc.NamedPipe.csproj

@@ -2,7 +2,6 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <Version>2.1.18-preview4</Version>
     <Description>https://github.com/serset/Sers</Description>
   </PropertyGroup>
 

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Sers.CL.Ipc.NamedPipe.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.SharedMemory/Sers.CL.Ipc.SharedMemory.csproj

@@ -2,7 +2,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Sers.CL.Socket.Iocp.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.ThreadWait/Sers.CL.Socket.ThreadWait.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 4 - 4
dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/ProgramQps.cs

@@ -21,7 +21,7 @@ namespace CLClient
             qpsInfo.Start("Msg");
 
 
-            for (int i = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<int>("PressureTest.clientCount"); i >0; i--)
+            for (int i = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<int>("PressureTest.clientCount"); i >0; i--)
             {
                 StartThreadSendMessage();
             }
@@ -75,16 +75,16 @@ namespace CLClient
             }
 
 
-            byte[] buff = new byte[Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<int>("PressureTest.msgLen")];
+            byte[] buff = new byte[Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<int>("PressureTest.msgLen")];
 
 
-            for (int i = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<int>("PressureTest.messageThreadCount"); i > 0; i--)
+            for (int i = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<int>("PressureTest.messageThreadCount"); i > 0; i--)
             {
                 cm.SendMessageAsync(new ByteData(buff));
             }
 
 
-            int theadCount = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<int>("PressureTest.requestThreadCount");
+            int theadCount = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<int>("PressureTest.requestThreadCount");
 
             if (theadCount >= 0)
             {

+ 4 - 1
dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/appsettings.json

@@ -120,7 +120,10 @@
 
           /* (x.2) config */
           /* 服务端地址(默认为 "ws://127.0.0.1:4503") */
-          "host": "ws://127.0.0.1:4503"
+          "host": "ws://127.0.0.1:4503",
+
+          /* 是否校验服务端证书(使用wss时有效),default:true  */
+          "//validateRemoteCertificate": false
 
         },
 

+ 7 - 1
dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmServer/appsettings.json

@@ -116,7 +116,13 @@
 
           /* (x.2) config */
           /* 服务端地址(默认为 "ws://0.0.0.0:4503") */
-          "host": "ws://0.0.0.0:4503"
+          "host": "ws://0.0.0.0:4503",
+
+          /* SSL证书(若使用wss则必须指定证书) */
+          "//certificate": {
+            "filePath": "Data/ssl.pfx",
+            "password": ""
+          }
 
         },
 

+ 22 - 0
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/DeliveryClient.cs

@@ -5,6 +5,7 @@ using System.Net.WebSockets;
 using System.Threading;
 using Sers.Core.CL.MessageDelivery;
 using Vit.Core.Module.Log;
+using Vit.Extensions.ObjectExt;
 
 namespace Sers.CL.WebSocket
 {
@@ -27,13 +28,34 @@ namespace Sers.CL.WebSocket
         public string host = "ws://127.0.0.1:4503";
 
 
+        /// <summary>
+        /// 是否校验服务端证书(使用wss时有效),default:true
+        /// </summary>
+        public bool? validateRemoteCertificate;
+
         public bool Connect()
         {
             try
             {
                 Logger.Info("[CL.DeliveryClient] WebSocket,connecting", new { host });
 
+
                 ClientWebSocket _webSocket = new ClientWebSocket();
+
+                if (validateRemoteCertificate == false)
+                {
+                    try
+                    {
+                        System.Net.Security.RemoteCertificateValidationCallback callback = delegate { return true; };
+                        _webSocket.Options.SetProperty("RemoteCertificateValidationCallback", callback);
+                    }
+                    catch (Exception ex)
+                    {
+                        Logger.Error(ex);
+                    }
+                }
+
+
                 _webSocket.ConnectAsync(new Uri(host), new CancellationToken()).GetAwaiter().GetResult();
                 _conn.Init(_webSocket);                
 

+ 30 - 1
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/DeliveryServer.cs

@@ -6,9 +6,12 @@ using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Cryptography.X509Certificates;
 
 using Fleck;
 
+using Newtonsoft.Json;
+
 using Sers.Core.CL.MessageDelivery;
 
 using Vit.Core.Module.Log;
@@ -20,10 +23,30 @@ namespace Sers.CL.WebSocket
         public Sers.Core.Util.StreamSecurity.SecurityManager securityManager;
 
         /// <summary>
-        /// 服务端地址(默认为 "ws://0.0.0.0:4503")
+        /// server address(default: "ws://0.0.0.0:4503")
         /// </summary>
         public string host = "ws://0.0.0.0:4503";
 
+        /// <summary>
+        /// 
+        /// </summary>
+        public CertificateInfo certificate;
+
+        #region CertificateInfo
+        [JsonObject(MemberSerialization.OptIn)]
+        public class CertificateInfo
+        {
+            /// <summary>
+            /// Data/ssl.pfx
+            /// </summary>
+            [JsonProperty]
+            public string filePath { get; set; }
+
+            [JsonProperty]
+            public string password { get; set; }
+
+        }
+        #endregion
 
         public Action<IDeliveryConnection> Conn_OnDisconnected { private get; set; }
         public Action<IDeliveryConnection> Conn_OnConnected { private get; set; }
@@ -42,6 +65,12 @@ namespace Sers.CL.WebSocket
 
                 listenSocket = new WebSocketServer(host);
 
+                if (certificate != null)
+                {
+                    listenSocket.Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.filePath, certificate.password,
+                        X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
+                }
+
                 //出错后进行重启
                 listenSocket.RestartAfterListenError = true;
 

+ 2 - 1
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/OrganizeClientBuilder.cs

@@ -20,7 +20,8 @@ namespace Sers.CL.WebSocket
             }
             #endregion
 
-            delivery.host = config["host"].ConvertToString() ?? delivery.host;
+            delivery.host = config["host"]?.ConvertToString() ?? delivery.host;
+            delivery.validateRemoteCertificate = config["validateRemoteCertificate"]?.Deserialize<bool?>() ?? delivery.validateRemoteCertificate;
 
 
             organizeList.Add(new OrganizeClient(delivery, config));

+ 3 - 1
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/OrganizeServerBuilder.cs

@@ -20,7 +20,9 @@ namespace Sers.CL.WebSocket
             }
             #endregion
 
-            delivery.host = config["host"].ConvertToString() ?? delivery.host;
+            delivery.host = config["host"]?.ConvertToString() ?? delivery.host;
+
+            delivery.certificate = config["certificate"]?.Deserialize<DeliveryServer.CertificateInfo>() ?? delivery.certificate;
 
             organizeList.Add(new OrganizeServer(delivery, config));
         }

+ 1 - 1
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/Sers.CL.WebSocket.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Zmq/FullDuplex/Sers.CL.Zmq.FullDuplex/Sers.CL.Zmq.FullDuplex.csproj

@@ -3,7 +3,7 @@
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
 		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Zmq/ThreadWait/Sers.CL.ClrZmq.ThreadWait/Sers.CL.ClrZmq.ThreadWait.csproj

@@ -2,7 +2,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 0 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core.Temp/Sers.Core.Temp.csproj

@@ -2,7 +2,6 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <Version>2.1.18-preview4</Version>
   </PropertyGroup>
   
   <PropertyGroup>

+ 2 - 2
dotnet/Library/Sers/Sers.Core/Sers.Core/CL/CommunicationManage/CommunicationManageClient.cs

@@ -16,7 +16,7 @@ namespace Sers.Core.CL.CommunicationManage
 
         public CommunicationManageClient()
         {
-            defaultConfig= ConfigurationManager.Instance.GetByPath<JObject>("Sers.CL.Config")??new JObject();
+            defaultConfig= Appsettings.json.GetByPath<JObject>("Sers.CL.Config") ?? new JObject();
 
             requestTimeoutMs = defaultConfig["requestTimeoutMs"]?.ConvertBySerialize<int?>() ?? 300000;
         }
@@ -125,7 +125,7 @@ namespace Sers.Core.CL.CommunicationManage
 
 
                 #region (x.1) get configs
-                var configs = ConfigurationManager.Instance.GetByPath<JObject[]>("Sers.CL.Client");
+                var configs = Appsettings.json.GetByPath<JObject[]>("Sers.CL.Client");
                 if (configs == null) 
                 {
                     //return null;

+ 2 - 2
dotnet/Library/Sers/Sers.Core/Sers.Core/CL/CommunicationManage/CommunicationManageServer.cs

@@ -25,7 +25,7 @@ namespace Sers.Core.CL.CommunicationManage
 
         public CommunicationManageServer()
         {
-            defaultConfig = ConfigurationManager.Instance.GetByPath<JObject>("Sers.CL.Config") ?? new JObject();
+            defaultConfig = Appsettings.json.GetByPath<JObject>("Sers.CL.Config") ?? new JObject();
 
             requestTimeoutMs = defaultConfig["requestTimeoutMs"]?.ConvertBySerialize<int?>() ?? 300000;
         }
@@ -130,7 +130,7 @@ namespace Sers.Core.CL.CommunicationManage
 
    
                 #region (x.1) get configs
-                var configs = ConfigurationManager.Instance.GetByPath<JObject[]>("Sers.CL.Server");
+                var configs = Appsettings.json.GetByPath<JObject[]>("Sers.CL.Server");
                 if (configs == null) return null;
                 foreach (var config in configs)
                 {

+ 2 - 2
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Api/LocalApi/LocalApiService/LocalApiService.cs

@@ -27,7 +27,7 @@ namespace Sers.Core.Module.Api.LocalApi
 
         public LocalApiService()
         {
-            workThread = ConsumerFactory.CreateConsumer<RequestInfo>(ConfigurationManager.Instance.GetByPath<JObject>("Sers.LocalApiService.workThread"));
+            workThread = ConsumerFactory.CreateConsumer<RequestInfo>(Appsettings.json.GetByPath<JObject>("Sers.LocalApiService.workThread"));
 
             workThread.threadName = "LocalApiService";
             workThread.Processor = Consumer_Processor;
@@ -36,7 +36,7 @@ namespace Sers.Core.Module.Api.LocalApi
 
         public void Init()
         {
-            var localApiServiceConfig = ConfigurationManager.Instance.GetByPath<JToken>("Sers.LocalApiService");
+            var localApiServiceConfig = Appsettings.json.GetByPath<JToken>("Sers.LocalApiService");
             if (localApiServiceConfig != null)
                 localApiEventMng.Init(localApiServiceConfig);
         }

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Api/LocalApi/StaticFileTransmit/Extensions/ILocalApiService_StaticFileMap_Extensions.cs

@@ -25,7 +25,7 @@ namespace Vit.Extensions
                 return;
             }
 
-            var configs = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<StaticFilesApiNodeConfig[]>("Sers.LocalApiService.staticFiles");
+            var configs = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<StaticFilesApiNodeConfig[]>("Sers.LocalApiService.staticFiles");
 
             if (configs == null || configs.Length == 0) return;
 

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiLoader/ApiLoaderMng.cs

@@ -18,7 +18,7 @@ namespace Sers.Core.Module.ApiLoader
         public IEnumerable<IApiNode> LoadApi()
         {
       
-            var configs = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<JObject[]>("Sers.LocalApiService.ApiLoaders");
+            var configs = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<JObject[]>("Sers.LocalApiService.ApiLoaders");
             if (configs == null || configs.Length == 0) return null;
 
             List<IApiNode> apiNodes = new List<IApiNode>();

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/ApiTraceMng.cs

@@ -45,7 +45,7 @@ namespace Sers.Core.Module.ApiTrace
             #endregion
 
 
-            var configs = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<JObject[]>("Sers.ApiTrace.Collector");
+            var configs = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<JObject[]>("Sers.ApiTrace.Collector");
             if (configs == null || configs.Length == 0) return;
 
             Logger.Info("[ApiTraceMng]collector loading");

+ 60 - 0
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/ElasticSearchCollector.appsettings.json

@@ -0,0 +1,60 @@
+{
+  "Sers": {
+
+    /* ApiTrace 搜集器配置,可不指定 */
+    "ApiTrace": {
+      "Collector": [
+        { //搜集ApiTrace到 ElasticSearch
+
+          /* 搜集器名称(ApiTrace推送端根据此名称推送到对应的搜集器),若不指定则不加载 */
+          "collectorName": "default",
+
+          /* 在此Assembly中加载类 */
+          "assemblyFile": "Sers.Core.dll",
+          /* 动态加载的类名,必须继承接口 Sers.Core.Module.ApiTrace.Collector.IApiTraceCollector */
+          "className": "Sers.Core.Module.ApiTrace.Collector.ElasticSearchCollector",
+
+
+          "server": {
+            // es address, example:"http://192.168.20.20:9200"
+            "url": "http://192.168.20.20:9200",
+            //es index, example:"dev"
+            "index": "dev_apitrace",
+            //es type, example:"_doc"
+            //"type": "_doc",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
+          },
+
+          //custome object
+          "//appInfo": {
+            "namespace": "mc.sers.cloud",
+            "appName": "mc",
+            "moduleName": "sers"
+            //,"...": {}
+          },
+
+          "//tags": {
+            // 可为 requestRpc requestData responseRpc responseData
+            "route": "{{requestRpc.route}}",
+            //"{{requestRpc.route}}": "route",
+
+            "url": "{{requestRpc.http.url}}",
+            "method": "{{requestRpc.http.method}}",
+            "requestRpc": "{{requestRpc}}",
+            "requestData": "{{requestData}}",
+
+            "responseRpc": "{{responseRpc}}",
+            "responseState": "{{responseRpc.http.headers.responseState}}",
+            //"responseError_Base64": "{{responseRpc.http.headers.responseError_Base64}}"
+
+            "responseData": "{{responseData}}",
+            "responseData.error": "{{responseData.error}}"
+          }
+        }
+      ]
+    }
+
+  }
+
+}

+ 88 - 0
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/ElasticSearchCollector.cs

@@ -0,0 +1,88 @@
+using Newtonsoft.Json.Linq;
+using Sers.Core.Module.Message;
+using Sers.Core.Module.Rpc;
+
+using System;
+using System.Collections.Generic;
+using Vit.Extensions;
+using Vit.Core.Module.Log;
+using Vit.Core.Module.Log.LogCollector.ElasticSearch.Client;
+using Newtonsoft.Json;
+
+namespace Sers.Core.Module.ApiTrace.Collector
+{
+    public class ElasticSearchCollector : IApiTraceCollector
+    {
+        // ElasticSearch ApiTrace Record Format:
+        // "index": "dev", "type": "_doc"
+        /* 
+        {
+            "@timestamp":1653468236619,
+            "time": "2022-05-25T08:19:36.686Z", 
+
+            "level": "ApiTrace",
+            "apiTrace": {
+                "beginTime":"2022-03-26 02:52:00.123456",
+                "endTime":"2022-03-26 02:52:04.123456",
+                "duration":"4000.0",
+
+                //extTags
+            },
+
+            //custome object
+            "appInfo": {
+                "namespace": "mc.sers.cloud",
+                "appName": "mc",
+                "moduleName": "sers"
+                //,"...": {}
+            }
+        }
+        */
+        public class ApiTraceRecord : ElasticSearchRecord
+        {
+            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+            public string level;
+
+            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+            public JObject apiTrace;
+        }
+
+
+        ElasticSearchClient client;
+        JObject appInfo;
+
+        IDictionary<string, string> tagsTemplate;
+
+        public void Init(JObject arg)
+        {
+            Logger.Info("[ApiTrace.ElasticSearchCollector] init ...");
+            client = arg["server"].Deserialize<ElasticSearchClient>();
+
+            appInfo = arg?["appInfo"]?.Deserialize<JObject>();
+            tagsTemplate = arg?["tags"]?.Deserialize<IDictionary<string, string>>();
+
+            client?.Init();
+        }
+        
+
+        public object TraceStart(RpcContextData rpcData)
+        {
+            return DateTime.Now;
+        }
+        public void TraceEnd(object traceData, RpcContextData rpcData, ApiMessage apiRequestMessage, Func<ApiMessage> GetApiReplyMessage)
+        {
+            JObject eventData = SplunkCollector.BuildEventData(traceData, rpcData, apiRequestMessage, GetApiReplyMessage, tagsTemplate);
+
+            var record = new ApiTraceRecord
+            {
+                Time = DateTime.UtcNow,
+
+                level = "ApiTrace",
+                apiTrace = eventData,
+
+                appInfo = appInfo
+            };
+            client.SendAsync(record);
+        }
+    }
+}

+ 0 - 10
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/IApiTraceCollector.cs

@@ -11,20 +11,10 @@ namespace Sers.Core.Module.ApiTrace.Collector
     {
         void Init(JObject config);
 
-        void AppBeforeStart();
-
-        void AppBeforeStop();
-
-
-
-
  
         object TraceStart(RpcContextData rpcData);
 
  
         void TraceEnd(object traceData, RpcContextData rpcData, ApiMessage apiRequestMessage, Func<ApiMessage> GetApiReplyMessage);
-
-
-
     }
 }

+ 7 - 5
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/SplunkCollector.appsettings.json

@@ -15,13 +15,15 @@
           "className": "Sers.Core.Module.ApiTrace.Collector.SplunkCollector",
 
 
-          "client": {
+          "server": {
             "url": "http://192.168.20.20:8088/services/collector",
-            "authToken": "xxxxx"
+            "authToken": "xxxxx",
+            "index": "dev",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
           },
 
-          "//message": {
-            "index": "dev",
+          "//hostInfo": {
             "host": "192.168.20.20:8088",
             "source": "http:mc",
             "sourcetype": "httpevent"
@@ -35,7 +37,7 @@
             //,"...": {}
           },
 
-          "//tags": {
+          "tags": {
             // 可为 requestRpc requestData responseRpc responseData
             "route": "{{requestRpc.route}}",
             //"{{requestRpc.route}}": "route",

+ 68 - 56
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/SplunkCollector.cs

@@ -6,83 +6,103 @@ using System;
 using System.Collections.Generic;
 using Vit.Extensions;
 using Vit.Core.Module.Log;
-using Vit.Core.Module.Log.LogCollector.Splunk;
+using Vit.Core.Module.Log.LogCollector.Splunk.Client;
 
 namespace Sers.Core.Module.ApiTrace.Collector
 {
     public class SplunkCollector : IApiTraceCollector
     {
-        /*
-{
-    "host": "localhost",
-    "source": "random-data-generator",
-    "sourcetype": "my_sample_data",
-    "index": "dev",
-    "event": { 
-        "level": "ApiTrace",
-
-        "appInfo": { //custome object
-            "namespace": "mc.sers.cloud",
-            "appName": "mc",
-            "moduleName": "sers"
-            //,"...": {}
-        },
-
-        "beginTime":"2022-03-26 02:52:00.123456",
-        "endTime":"2022-03-26 02:52:04.123456",
-        "duration":"4000.0",
-
-        //extTags
-    }
-}
+        // Splunk ApiTrace Record Format:
+        /* 
+        {
+            "time": 1426279439.123,
+
+            "index": "dev",
+
+            "host": "localhost",
+            "source": "random-data-generator",
+            "sourcetype": "my_sample_data",
+
+            "event": { 
+                "level": "ApiTrace",
+
+                "appInfo": { //custome object
+                    "namespace": "mc.sers.cloud",
+                    "appName": "mc",
+                    "moduleName": "sers"
+                    //,"...": {}
+                },
+
+                "beginTime":"2022-03-26 02:52:00.123456",
+                "endTime":"2022-03-26 02:52:04.123456",
+                "duration":"4000.0",
+
+                //extTags
+            }
+        }
         */
 
 
 
         SplunkClient client;
-        SplunkRecord message;
+        SplunkRecord hostInfo;
         JObject appInfo;
 
         IDictionary<string, string> tagsTemplate;
 
         public void Init(JObject arg)
         {
-            Logger.Info("[ApiTrace.SplunkCollector]初始化中");
-            client = arg["client"].Deserialize<SplunkClient>();
-            client.Init();
-            message = arg?["message"]?.Deserialize<SplunkRecord>();
+            Logger.Info("[ApiTrace.SplunkCollector] init ...");
+            client = arg["server"].Deserialize<SplunkClient>();
+
+            hostInfo = arg?["hostInfo"]?.Deserialize<SplunkRecord>();
             appInfo = arg?["appInfo"]?.Deserialize<JObject>();
             tagsTemplate = arg?["tags"]?.Deserialize<IDictionary<string, string>>();
-        }
-
-        public void AppBeforeStart()
-        {
-            Logger.Info("[ApiTrace.SplunkCollector]初始化成功");
-        }
-
-        public void AppBeforeStop()
-        {
 
+            client?.Init();
         }
 
         public object TraceStart(RpcContextData rpcData)
         {
             return DateTime.Now;
         }
+
         public void TraceEnd(object traceData, RpcContextData rpcData, ApiMessage apiRequestMessage, Func<ApiMessage> GetApiReplyMessage)
         {
-            var beginTime = (DateTime)traceData;
+            JObject eventData = BuildEventData(traceData, rpcData, apiRequestMessage, GetApiReplyMessage, tagsTemplate);
+            if (appInfo != null) eventData["appInfo"] = appInfo;
+
+            var record = new SplunkRecord
+            {
+                Time = DateTime.UtcNow,
+                index = hostInfo?.index,
 
-            var endTime = DateTime.Now;
+                host = hostInfo?.host ?? Environment.MachineName,
+                source = hostInfo?.source,
+                sourcetype = hostInfo?.sourcetype,
 
+                @event = eventData
+            };
+            client.SendAsync(record);
+        }
+
+
+
+        #region BuildEventData    
+        public static JObject BuildEventData(object beginTime, RpcContextData rpcData, ApiMessage apiRequestMessage, Func<ApiMessage> GetApiReplyMessage, IDictionary<string, string> tagsTemplate)
+        {
 
             JObject eventData = new JObject();
             eventData["level"] = "ApiTrace";
-            if (appInfo != null) eventData["appInfo"] = appInfo;
 
-            eventData["beginTime"] = beginTime.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
-            eventData["endTime"] = endTime.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
-            eventData["duration"] = (endTime - beginTime).TotalMilliseconds;
+            if (beginTime is DateTime _beginTime) 
+            {
+                var endTime = DateTime.Now;
+
+                eventData["beginTime"] = _beginTime.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
+                eventData["endTime"] = endTime.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
+                eventData["duration"] = (endTime - _beginTime).TotalMilliseconds;
+            }
 
 
             #region method getTagValue
@@ -206,7 +226,7 @@ namespace Sers.Core.Module.ApiTrace.Collector
             #endregion
 
 
- 
+
             tagsTemplate?.IEnumerable_ForEach(item =>
             {
                 var key = GetTagValue(item.Key)?.ConvertToString();
@@ -217,18 +237,10 @@ namespace Sers.Core.Module.ApiTrace.Collector
 
             });
 
-            var record = new SplunkRecord
-            {
-                index = message?.index,
-                host = message?.host ?? Environment.MachineName,
-                source = message?.source,
-                sourcetype = message?.sourcetype,
+            return eventData;
+        }
 
-                @event = eventData
-            };
-            client.SendAsync(record);
+        #endregion
 
- 
-        }
     }
 }

+ 6 - 138
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/ApiTrace/Collector/TxtCollector.cs

@@ -16,21 +16,11 @@ namespace Sers.Core.Module.ApiTrace.Collector
         IDictionary<string, string> tagsTemplate;
         public void Init(JObject arg)
         {
-            Logger.Info("[ApiTrace.TxtCollector]初始化中");
+            Logger.Info("[ApiTrace.TxtCollector] init ...");
 
             tagsTemplate = arg?["tags"]?.Deserialize<IDictionary<string, string>>();
         }
 
-        public void AppBeforeStart()
-        {
-            Logger.Info("[ApiTrace.TxtCollector]初始化成功");
-        }
-
-        public void AppBeforeStop()
-        {
-
-        }
-
         Vit.Core.Module.Log.LogCollector.TxtCollector logCollector = new Vit.Core.Module.Log.LogCollector.TxtCollector();
 
         public object TraceStart(RpcContextData rpcData)
@@ -44,128 +34,6 @@ namespace Sers.Core.Module.ApiTrace.Collector
             var endTime = DateTime.Now;
 
 
-            #region method getTagValue
-
-            string requestRpc_oriString = null;
-            JObject requestRpc_json = null;
-
-            string requestData_oriString = null;
-            JObject requestData_json = null;
-
-            ApiMessage apiResponseMessage = null;
-
-            string responseRpc_oriString = null;
-            JObject responseRpc_json = null;
-
-            string responseData_oriString = null;
-            JObject responseData_json = null;
-
-            string GetTagValue(string valueString)
-            {
-                if (string.IsNullOrEmpty(valueString)) return null;
-                if (!valueString.StartsWith("{{") || !valueString.EndsWith("}}")) return valueString;
-
-                try
-                {
-
-                    valueString = valueString.Substring(2, valueString.Length - 4);
-
-                    string dataType;
-                    string path;
-
-                    var splitIndex = valueString.IndexOf('.');
-                    if (splitIndex < 0)
-                    {
-                        dataType = valueString;
-                        path = "";
-                    }
-                    else
-                    {
-                        dataType = valueString.Substring(0, splitIndex);
-                        path = valueString.Substring(splitIndex + 1);
-                    }
-
-                    switch (dataType)
-                    {
-                        case "requestRpc":
-
-                            if (requestRpc_oriString == null)
-                            {
-                                requestRpc_oriString = apiRequestMessage.rpcContextData_OriData.ArraySegmentByteToString();
-                            }
-                            if (string.IsNullOrEmpty(path))
-                            {
-                                return requestRpc_oriString;
-                            }
-                            if (requestRpc_json == null)
-                            {
-                                requestRpc_json = requestRpc_oriString.Deserialize<JObject>();
-                            }
-                            return requestRpc_json?.SelectToken(path).ConvertToString();
-
-                        case "requestData":
-                            if (requestData_oriString == null)
-                            {
-                                requestData_oriString = apiRequestMessage.value_OriData.ArraySegmentByteToString();
-                            }
-                            if (string.IsNullOrEmpty(path))
-                            {
-                                return requestData_oriString;
-                            }
-                            if (requestData_json == null)
-                            {
-                                requestData_json = requestData_oriString.Deserialize<JObject>();
-                            }
-                            return requestData_json?.SelectToken(path).ConvertToString();
-
-                        case "responseRpc":
-                            if (apiResponseMessage == null)
-                            {
-                                apiResponseMessage = GetApiReplyMessage();
-                            }
-                            if (responseRpc_oriString == null)
-                            {
-                                responseRpc_oriString = apiResponseMessage.rpcContextData_OriData.ArraySegmentByteToString();
-                            }
-                            if (string.IsNullOrEmpty(path))
-                            {
-                                return responseRpc_oriString;
-                            }
-                            if (responseRpc_json == null)
-                            {
-                                responseRpc_json = responseRpc_oriString.Deserialize<JObject>();
-                            }
-                            return responseRpc_json?.SelectToken(path).ConvertToString();
-
-                        case "responseData":
-                            if (apiResponseMessage == null)
-                            {
-                                apiResponseMessage = GetApiReplyMessage();
-                            }
-                            if (responseData_oriString == null)
-                            {
-                                responseData_oriString = apiResponseMessage.value_OriData.ArraySegmentByteToString();
-                            }
-                            if (string.IsNullOrEmpty(path))
-                            {
-                                return responseData_oriString;
-                            }
-                            if (responseData_json == null)
-                            {
-                                responseData_json = responseData_oriString.Deserialize<JObject>();
-                            }
-                            return responseData_json?.SelectToken(path).ConvertToString();
-                    }
-                }
-                catch
-                {
-                }
-                return null;
-            }
-            #endregion
-
-
-
             StringBuilder msg = new StringBuilder(1024 * 4);
 
             msg.Append(Environment.NewLine).Append("┍------------ ---------┑");
@@ -175,16 +43,16 @@ namespace Sers.Core.Module.ApiTrace.Collector
             msg.Append(Environment.NewLine).Append("--duration :").Append((endTime - beginTime).TotalMilliseconds).Append(" ms");
 
 
-            tagsTemplate?.IEnumerable_ForEach(item =>
+            JObject eventData = SplunkCollector.BuildEventData(null, rpcData, apiRequestMessage, GetApiReplyMessage, tagsTemplate);
+            foreach (var kv in eventData)
             {
-                var key = GetTagValue(item.Key);
-                var value = GetTagValue(item.Value);
+                var key = kv.Key;
+                var value = kv.Value;
                 if (key != null)
                 {
                     msg.Append(Environment.NewLine).Append("--" + key + ":").Append(value);
                 }
-            });
-
+            }
 
             msg.Append(Environment.NewLine).Append("┕------------ ---------┙").Append(Environment.NewLine);
 

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/App/SersApplication.cs

@@ -174,7 +174,7 @@ namespace Sers.Core.Module.App
         {
             #region (x.1)serviceStationInfo
             {
-                serviceStationInfo = ConfigurationManager.Instance.GetByPath<ServiceStationInfo>("Sers.ServiceStation.serviceStationInfo") 
+                serviceStationInfo = Appsettings.json.GetByPath<ServiceStationInfo>("Sers.ServiceStation.serviceStationInfo") 
                     ?? new ServiceStationInfo();
 
                 //(x.1) stationVersion

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Env/UsageReporter.cs

@@ -91,7 +91,7 @@ namespace Sers.Core.Module.Env
         /// </summary>
         public static void UseUsageReporter()
         {
-            var intervalSecond = ConfigurationManager.Instance.GetByPath<double?>("Sers.ServiceStation.UsageReporter.intervalSecond");
+            var intervalSecond = Appsettings.json.GetByPath<double?>("Sers.ServiceStation.UsageReporter.intervalSecond");
             if (!intervalSecond.HasValue || intervalSecond.Value <= 0)
             {
                 return;

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/Controller/SubscriberLoader.cs

@@ -18,7 +18,7 @@ namespace Sers.Core.Module.PubSub.Controller
             foreach (var type in types)
             {
                 ISubscriber subscriber = (ISubscriber)Activator.CreateInstance(type);
-                EndpointManage.Instance.Message_Subscribe(subscriber);
+                SubscriberManage.Instance.Message_Subscribe(subscriber);
             }
         }
     }

+ 8 - 8
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/EFrameType.cs

@@ -3,20 +3,20 @@
     public enum EFrameType : byte
     {
         /// <summary>
-        ///  publish,msgTitle,msgData
+        ///  publish, msgTitle, msgData
         /// </summary>
-        publish,
+        publish = 0,
         /// <summary>
-        /// subscribe,msgTitle
+        /// subscribe, msgTitle
         /// </summary>
-        subscribe,
+        subscribe = 1,
         /// <summary>
-        /// subscribeCancel,msgTitle
+        /// unSubscribe, msgTitle
         /// </summary>
-        subscribeCancel,
+        unSubscribe = 2,
         /// <summary>
-        /// message,msgTitle,msgData
+        /// message, msgTitle, msgData
         /// </summary>
-        message
+        message = 3
     }
 }

+ 2 - 2
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/HotPlugSubscriber.cs

@@ -21,7 +21,7 @@ namespace Sers.Core.Module.PubSub
         public void Subscribe()
         {
             if (subscribing) return;
-            EndpointManage.Instance.Message_Subscribe(this);
+            SubscriberManage.Instance.Message_Subscribe(this);
             subscribing = true;
         }
 
@@ -32,7 +32,7 @@ namespace Sers.Core.Module.PubSub
         {
             if (subscribing)
             {
-                EndpointManage.Instance.Message_SubscribeCancel(this);
+                SubscriberManage.Instance.Message_UnSubscribe(this);
                 subscribing = false;
             }
             

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/MessageCenterService.cs

@@ -45,7 +45,7 @@ namespace Sers.Core.Module.PubSub
                     case (byte)EFrameType.subscribe:
                         Subscribe(conn, msgTitle);
                         break;
-                    case (byte)EFrameType.subscribeCancel:
+                    case (byte)EFrameType.unSubscribe:
                         SubscribeCancel(conn, msgTitle);
                         break;
                 }

+ 5 - 7
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/MessageClient.cs

@@ -1,12 +1,10 @@
 using Vit.Core.Module.Log;
 using System;
-using System.Collections.Generic;
 using System.Threading.Tasks;
 using Sers.Core.Module.Message;
 using Vit.Extensions;
 using System.Collections.Concurrent;
 using Sers.Core.CL.MessageOrganize;
-using Vit.Core.Util.Pipelines;
 using System.Runtime.CompilerServices;
 
 namespace Sers.Core.Module.PubSub
@@ -98,7 +96,7 @@ namespace Sers.Core.Module.PubSub
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public void Message_Publish(string msgTitle, ArraySegment<byte> msgData)
         {
-            //publish,msgTitle,msgData 
+            //EFrameType.publish, msgTitle, msgData 
             var frame = new SersFile().SetFiles(
                 new[] { (byte)EFrameType.publish }.BytesToArraySegmentByte(),
                  msgTitle.SerializeToArraySegmentByte(),
@@ -109,7 +107,7 @@ namespace Sers.Core.Module.PubSub
 
         public void Message_Subscribe(string msgTitle)
         {
-            //subscribe,msgTitle
+            //EFrameType.subscribe, msgTitle
             var frame = new SersFile().SetFiles(
                 new[] { (byte)EFrameType.subscribe }.BytesToArraySegmentByte(),
                  msgTitle.SerializeToArraySegmentByte()
@@ -117,11 +115,11 @@ namespace Sers.Core.Module.PubSub
             SendFrame(frame);
         }
 
-        public void Message_SubscribeCancel(string msgTitle)
+        public void Message_UnSubscribe(string msgTitle)
         {
-            //subscribeCancel,msgTitle
+            //EFrameType.unSubscribe, msgTitle
             var frame = new SersFile().SetFiles(
-                new[] { (byte)EFrameType.subscribeCancel }.BytesToArraySegmentByte(),
+                new[] { (byte)EFrameType.unSubscribe }.BytesToArraySegmentByte(),
                  msgTitle.SerializeToArraySegmentByte()
                 ).Package();
             SendFrame(frame);

+ 6 - 6
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/EndpointManage.cs → dotnet/Library/Sers/Sers.Core/Sers.Core/Module/PubSub/SubscriberManage.cs

@@ -6,12 +6,12 @@ using System.Runtime.CompilerServices;
 
 namespace Sers.Core.Module.PubSub
 {
-    public class EndpointManage
+    public class SubscriberManage
     {
-        public static readonly EndpointManage Instance = new EndpointManage();
+        public static readonly SubscriberManage Instance = new SubscriberManage();
 
 
-        public EndpointManage()
+        public SubscriberManage()
         {
             MessageClient.Instance.Message_Consumer = Message_Consumer;
         }
@@ -64,7 +64,7 @@ namespace Sers.Core.Module.PubSub
                 subscriberList.TryAdd(subscriber.GetHashCode(), subscriber);
             }
         }
-        public void Message_SubscribeCancel(HotPlugSubscriber subscriber)
+        public void Message_UnSubscribe(HotPlugSubscriber subscriber)
         {
             lock (this)
             {
@@ -74,7 +74,7 @@ namespace Sers.Core.Module.PubSub
                 if (subscriberList.IsEmpty)
                 {
                     subscriberMap.TryRemove(subscriber.msgTitle, out _);
-                    MessageClient.Instance.Message_SubscribeCancel(subscriber.msgTitle);
+                    MessageClient.Instance.Message_UnSubscribe(subscriber.msgTitle);
                 }
             }     
         }
@@ -82,7 +82,7 @@ namespace Sers.Core.Module.PubSub
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public void Message_Publish(string msgTitle, ArraySegment<byte> msgData)
         {
-            MessageClient.Instance.Message_Publish(msgTitle, msgData);
+            MessageClient.Publish(msgTitle, msgData);
         }
     }
 }

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Rpc/RpcContextData.cs

@@ -21,7 +21,7 @@ namespace Sers.Core.Module.Rpc
             // RpcData序列化模式。可不指定。默认为Text。
             // 可为 Newtonsoft、Text、BytePointor。
             // 效率依次递增。BytePointor 序列化为二进制数据而不是json字符串。
-            string rpcDataSerializeMode = ConfigurationManager.Instance.GetByPath<string>("Sers.RpcDataSerializeMode");
+            string rpcDataSerializeMode = Appsettings.json.GetByPath<string>("Sers.RpcDataSerializeMode");
  
             switch (rpcDataSerializeMode) 
             {

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Module/Serialization/Text/Serialization_Text.cs

@@ -38,7 +38,7 @@ namespace Sers.Core.Module.Serialization.Text
  
 
             //日期格式化
-            var DateTimeFormat = ConfigurationManager.Instance.GetByPath<string>("Vit.Serialization.DateTimeFormat")
+            var DateTimeFormat = Appsettings.json.GetByPath<string>("Vit.Serialization.DateTimeFormat")
               ?? "yyyy-MM-dd HH:mm:ss";
 
             jsonConverter_DateTime = options.AddConverter_DateTime(DateTimeFormat);

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Sers.Core.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/ApiLoader.cs

@@ -187,7 +187,7 @@ namespace Sers.SersLoader
 
 
             //(x.4)  appsettings.json指定
-            stationNames = ConfigurationManager.Instance.GetByPath<List<String>>("Sers.LocalApiService.apiStationNames");
+            stationNames = Appsettings.json.GetByPath<List<String>>("Sers.LocalApiService.apiStationNames");
             return stationNames;
 
         }

+ 5 - 5
dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/GatewayHelp.cs

@@ -27,7 +27,7 @@ namespace Sers.Gateway
 
         public static void Bridge()
         {
-            HostRunArg arg = ConfigurationManager.Instance.GetByPath<HostRunArg>("Sers.Gateway.WebHost");
+            HostRunArg arg = Appsettings.json.GetByPath<HostRunArg>("Sers.Gateway.WebHost");
             if (arg == null || arg.urls == null || arg.urls.Length == 0) return;
 
 
@@ -36,7 +36,7 @@ namespace Sers.Gateway
             var gatewayHelp = new GatewayHelp();
 
             #region (x.x.1)构建 Api Event BeforeCallApi
-            var BeforeCallApi = Sers.Core.Module.Api.ApiEvent.EventBuilder.LoadEvent_BeforeCallApi(ConfigurationManager.Instance.GetByPath<JArray>("Sers.Gateway.BeforeCallApi"));
+            var BeforeCallApi = Sers.Core.Module.Api.ApiEvent.EventBuilder.LoadEvent_BeforeCallApi(Appsettings.json.GetByPath<JArray>("Sers.Gateway.BeforeCallApi"));
             if (BeforeCallApi != null) gatewayHelp.BeforeCallApi += BeforeCallApi;
             #endregion
 
@@ -178,7 +178,7 @@ namespace Sers.Gateway
 
 
         #region BuildHttp
-        static string prefixOfCopyIpToHeader = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetStringByPath("Sers.Gateway.WebHost.prefixOfCopyIpToHeader");
+        static string prefixOfCopyIpToHeader = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetStringByPath("Sers.Gateway.WebHost.prefixOfCopyIpToHeader");
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         protected void BuildHttp(RpcContextData rpcData, HttpRequest request)
@@ -255,11 +255,11 @@ namespace Sers.Gateway
 
         #region WriteApiReplyMessage     
 
-        static string Rpc_CallerSource = ConfigurationManager.Instance.GetStringByPath("Sers.Gateway.Rpc.CallerSource") ?? "Outside";
+        static string Rpc_CallerSource = Appsettings.json.GetStringByPath("Sers.Gateway.Rpc.CallerSource") ?? "Outside";
 
         static readonly string Response_ContentType_Json = ("application/json; charset=" + Vit.Core.Module.Serialization.Serialization_Newtonsoft.Instance.charset);
 
-        static readonly string ResponseDefaultContentType = ConfigurationManager.Instance.GetStringByPath("Sers.Gateway.WebHost.ResponseDefaultContentType") ?? Response_ContentType_Json;
+        static readonly string ResponseDefaultContentType = Appsettings.json.GetStringByPath("Sers.Gateway.WebHost.ResponseDefaultContentType") ?? Response_ContentType_Json;
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]

+ 1 - 1
dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/RateLimit/RateLimitMng.cs

@@ -42,7 +42,7 @@ namespace Sers.Gateway.RateLimit
         /// </summary>
         public void LoadFromConfiguration()
         {
-            var rateLimits = ConfigurationManager.Instance.GetByPath<List<JObject>>("Sers.Gateway.rateLimit");
+            var rateLimits = Appsettings.json.GetByPath<List<JObject>>("Sers.Gateway.rateLimit");
             if (null != rateLimits)
             {
                 foreach (var item in rateLimits)

+ 1 - 1
dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/Sers.Gateway.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Hardware/Sers.Hardware/Sers.Hardware.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Extensions/ILocalApiService_LoadSerslotExtApi_Extensions.cs

@@ -19,7 +19,7 @@ namespace Vit.Extensions
         {
             if (CreateApiNode == null) CreateApiNode = apiDesc => new ApiNode_Original(apiDesc: apiDesc);
 
-            Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<List<SsApiDesc>>("serslot.extApi")?.ForEach(apiDesc =>
+            Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<List<SsApiDesc>>("serslot.extApi")?.ForEach(apiDesc =>
             {
                 IApiNode apiNode;
 

+ 1 - 1
dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Extensions/IWebHostBuilder_UseSerslot_Extensions.cs

@@ -15,7 +15,7 @@ namespace Vit.Extensions
         /// <returns></returns>
         public static IWebHostBuilder TryUseSerslot(this IWebHostBuilder hostBuilder)
         {
-            if (null == Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.Get<JToken>("Sers"))
+            if (null == Vit.Core.Util.ConfigurationManager.Appsettings.json.Get<JToken>("Sers"))
             {
                 return hostBuilder;
             }

+ 1 - 1
dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Sers.Serslot.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 10 - 8
dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/SerslotServer.cs

@@ -139,15 +139,17 @@ namespace Sers.Serslot
         // Graceful shutdown if possible
         public async Task StopAsync(CancellationToken cancellationToken)
         {
-
-            try
+            await Task.Run(() =>
             {
-                ServiceStation.ServiceStation.Stop();
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
+                try
+                {
+                    ServiceStation.ServiceStation.Stop();
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error(ex);
+                }
+            });
         }
 
         // Ungraceful shutdown

+ 1 - 1
dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/Sers.ServiceStation.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.18-preview4</Version>
+		<Version>2.1.18</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 9 - 4
dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/ServiceStation.cs

@@ -105,7 +105,7 @@ namespace Sers.ServiceStation
 
         public ServiceStation()
         {
-            appEventList = AppEventLoader.LoadAppEvent(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<JArray>("Sers.AppEvent"))
+            appEventList = AppEventLoader.LoadAppEvent(Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<JArray>("Sers.AppEvent"))
                 ?.ToList();
         }
 
@@ -126,8 +126,13 @@ namespace Sers.ServiceStation
 
         public void InitStation()
         {
-
-            Logger.Info("[ServiceStation] init...");
+            string FileVersion = null;
+            try
+            {
+                FileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetEntryAssembly().Location).FileVersion;
+            }
+            catch { }
+            Logger.Info("[ServiceStation] initializing", new { FileVersion });
 
             //(x.0) appEvent BeforeStart
             appEventList?.ForEach(ev => ev.BeforeStart());
@@ -292,7 +297,7 @@ namespace Sers.ServiceStation
                     localApiService.apiNodes
                 }.Serialize();
 
-                if (true == ConfigurationManager.Instance.GetByPath<bool?>("Sers.ServiceStation.StationRegist_PrintRegistArg"))
+                if (true == Appsettings.json.GetByPath<bool?>("Sers.ServiceStation.StationRegist_PrintRegistArg"))
                 {
                     Logger.Info("[ServiceStation] regist - arg:" + serviceStationData);
                 }

+ 4 - 2
dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Module/LoggerTest.cs

@@ -1,5 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System;
+using System.Threading;
+
 using Vit.Core.Module.Log;
 using Vit.Core.Util.ComponentModel.SsError;
 
@@ -19,12 +21,12 @@ namespace Vit.Core.MsTest.Module
             //»á½«ÈÕ־дÈë /Logs/{yyyy-MM}/{yyyy-MM-dd}Error.log
             Logger.Error("hello world!");
             Logger.Error(new Exception("hello world!"));
-            Logger.Error("error",new Exception("hello world!"));
+            Logger.Error("error", new Exception("hello world!"), new { a = 10 }, "message2", 12);
             Logger.Error(new SsError { errorCode = 404, errorMessage = "hello world!", errorTag = "150721_lith_1" });
             Logger.Error("error",new SsError { errorCode = 404, errorMessage = "hello world!", errorTag = "150721_lith_1" });
 
-                                        
 
+            Thread.Sleep(3000);
         }
     }
 }

+ 2 - 2
dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Module/SerializationTest.cs

@@ -30,13 +30,13 @@ namespace Vit.Core.MsTest.Module
 
 
             #region (x.2)object <--> String
-            Assert.AreEqual(Serialization.Instance.DeserializeFromString<ModelA>(Serialization.Instance.SerializeToString(modelA))?.name, testString);
+            Assert.AreEqual(Json.DeserializeFromString<ModelA>(Json.SerializeToString(modelA))?.name, testString);
             Assert.AreEqual(modelA.Serialize().Deserialize<ModelA>()?.name, testString);
             #endregion
 
 
             #region (x.3)object <--> bytes
-            Assert.AreEqual(Serialization.Instance.DeserializeFromBytes<ModelA>(Serialization.Instance.SerializeToBytes(modelA))?.name, testString);
+            Assert.AreEqual(Json.DeserializeFromBytes<ModelA>(Json.SerializeToBytes(modelA))?.name, testString);
             Assert.AreEqual(modelA.SerializeToBytes().DeserializeFromBytes<ModelA>()?.name, testString);
             #endregion
  

+ 0 - 27
dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Util/ComponentModel/ExceptionTest.cs

@@ -33,32 +33,5 @@ namespace Vit.Core.MsTest.Util.ComponentModel
 
         }
 
-
-
-        [TestMethod]
-        public void SersException_Test()
-        {
-
-            string msg = "";
-            SsException.Event_OnCreateException += (ex) =>
-            {
-                msg += "Event_OnCreateException called";
-            };
-
-            try
-            {
-
-                throw new SsException();
-            }
-            catch (System.Exception ex)
-            {
-            }
-
-            Assert.AreEqual(msg, "Event_OnCreateException called");
-
-            SsException.Event_OnCreateException = null;
-
-        }
-
     }
 }

+ 1 - 1
dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/Util/ConfigurationManager/ConfigurationManagerTest.cs

@@ -15,7 +15,7 @@ namespace Vit.Core.MsTest.Util.ConfigurationManager
         [TestMethod]
         public void Test()
         {
-            var Instance= Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance;
+            var Instance= Vit.Core.Util.ConfigurationManager.Appsettings.json;
 
             #region (x.1)DateTime 
             var date = Instance.Get<DateTime>("Test", "DateTime");

+ 34 - 7
dotnet/Library/Vit/Vit.Core/Test/Vit.Core.MsTest/appsettings.json

@@ -14,20 +14,22 @@
       "PrintLogErrorToConsole": false,
 
       /* [optional]collector to send log to */
-      "//Collector": [
+      "Collector": [
         {
           /* 在此Assembly中加载类 */
           "assemblyFile": "Vit.Core.dll",
           /* 动态加载的类名,必须继承接口 Vit.Core.Module.Log.LogCollector.ILogCollector */
-          "className": "Vit.Core.Module.Log.LogCollector.Splunk.SplunkCollector",
+          //"className": "Vit.Core.Module.Log.LogCollector.Splunk.SplunkCollector",
 
-          "client": {
-            "url": "http://192.168.20.20:8088/services/collector",
-            "authToken": "xxxxx"
+          "server": {
+            "url": "https://192.168.20.20:8088/services/collector",
+            "authToken": "xxxxx",
+            "index": "dev",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
           },
 
-          "//message": {
-            "index": "dev",
+          "//hostInfo": {            
             "host": "192.168.20.20:8088",
             "source": "http:mc",
             "sourcetype": "httpevent"
@@ -40,6 +42,31 @@
             "moduleName": "ServiceCenter"
             //,"...": {}
           }
+        },
+        {
+          /* 在此Assembly中加载类 */
+          "assemblyFile": "Vit.Core.dll",
+          /* 动态加载的类名,必须继承接口 Vit.Core.Module.Log.LogCollector.ILogCollector */
+          "className": "Vit.Core.Module.Log.LogCollector.ElasticSearch.ElasticSearchCollector",
+
+          "server": {
+            // es address, example:"http://192.168.20.20:9200"
+            "url": "http://192.168.20.20:9200",
+            //es index, example:"dev"
+            "index": "dev_log",
+            //es type, example:"_doc"
+            //"type": "_doc",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
+          },
+
+          //custome object
+          "appInfo": {
+            "namespace": "sers.cloud",
+            "appName": "mc",
+            "moduleName": "ServiceCenter"
+            //,"...": {}
+          }
         }
       ]
     }

+ 19 - 4
dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/EnumExtensions.cs

@@ -12,7 +12,24 @@ namespace Vit.Extensions
         #region String --> Enum
 
         /// <summary>
-        /// T 必须为Enum,且不可为Nullable
+        /// enumType must be Enum, can be Nullable
+        /// </summary>
+        /// <param name="data"></param>
+        /// <param name="enumType"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static object StringToEnum(this string data,Type enumType)
+        {
+            try
+            {
+                return Enum.Parse(enumType.GetUnderlyingTypeIfNullable(), data);
+            }
+            catch { }
+            return default;
+        }
+
+        /// <summary>
+        /// T must be Enum, can be Nullable
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <param name="data"></param>
@@ -22,15 +39,13 @@ namespace Vit.Extensions
         {
             try
             {
-                return (T)Enum.Parse(typeof(T), data);
+                return (T)Enum.Parse(typeof(T).GetUnderlyingTypeIfNullable(), data);
             }
             catch { }
             return default(T);
         }
 
 
-
-
         //public static string EnumToString(this Enum data)
         //{
         //    return data.ToString();

+ 1 - 1
dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/ObjectExt/ObjectExtExtensions.cs

@@ -73,7 +73,7 @@ namespace Vit.Extensions.ObjectExt
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static void SetProperty(this object instance, string propertyName, object value)
         {
-            instance.GetType().GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).SetValue(instance, value);            
+            instance.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).SetValue(instance, value);            
         }
 
         #endregion

+ 3 - 13
dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/ObjectExtensions.cs

@@ -18,7 +18,7 @@ namespace Vit.Extensions
             if (data == null)
             {
                 return false;
-                //throw new ArgumentNullException(nameof(type));
+                //throw new ArgumentNullException(nameof(data));
             }
             return data.GetType().TypeIsValueTypeOrStringType();
         }
@@ -28,7 +28,7 @@ namespace Vit.Extensions
         #region Convert
 
         /// <summary>
-        /// 若Type为Nullable类型(例如 long?)则转换为对应的值类型(例如long),否则直接转换。
+        /// 若Type为Nullable类型(例如 long?)则转换为对应的值类型(例如long),否则直接转换。(亦可为Enum类型)
         /// 若转换失败,会返回default(T)
         /// </summary>
         /// <typeparam name="T"></typeparam>
@@ -42,22 +42,12 @@ namespace Vit.Extensions
                 return default(T);
                 //throw new ArgumentNullException(nameof(value));
             }
-            //try
-            //{
             return (T)System.Convert.ChangeType(value, typeof(T).GetUnderlyingTypeIfNullable());
-            //}
-            //catch (System.Exception)
-            //{
-
-            //    throw;
-            //    return default(T);
-            //}
-
         }
 
 
         /// <summary>
-        /// 若为Nullable类型(例如 long?)则转换为对应的值类型(例如long),否则直接转换。
+        /// 若为Nullable类型(例如 long?)则转换为对应的值类型(例如long),否则直接转换。(亦可为Enum类型)
         /// </summary>
         /// <param name="type"></param>
         /// <param name="value"></param>

+ 4 - 6
dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/TypeExtensions.cs

@@ -1,7 +1,5 @@
 using System;
-using System.Collections.Generic;
 using System.Runtime.CompilerServices;
-using System.Text;
 
 namespace Vit.Extensions
 {
@@ -45,16 +43,16 @@ namespace Vit.Extensions
 
 
 
-        #region IfNullable
+        #region IsNullable
         /// <summary>
         /// 是否为Nullable类型(例如 long?)
         /// </summary>
         /// <param name="type"></param>
         /// <returns></returns>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static bool IfNullable(this Type type)
+        public static bool IsNullable(this Type type)
         {
-            return true== type?.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
+            return true == type?.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
         }
         #endregion
 
@@ -68,7 +66,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static global::System.Type GetUnderlyingTypeIfNullable(this global::System.Type type)
         {
-            return type.IfNullable() ? type.GetGenericArguments()[0] : type;
+            return type.IsNullable() ? type.GetGenericArguments()[0] : type;
 
 
             //if (type == null)

+ 26 - 5
dotnet/Library/Vit/Vit.Core/Vit.Core/Extensions/byte/ByteDataExtensions.cs

@@ -7,7 +7,6 @@ namespace Vit.Extensions
     public static partial class ByteDataExtensions
     {
 
-        #region ByteDataToBytes
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static byte[] ByteDataToBytes(this List<ArraySegment<byte>> byteData)
@@ -26,9 +25,9 @@ namespace Vit.Extensions
             int curIndex = 0;
             foreach (var item in byteData)
             {
-                if (null == item.Array || item.Count == 0) continue; 
+                if (null == item.Array || item.Count == 0) continue;
 
-                item.CopyTo(bytes, curIndex);                
+                item.CopyTo(bytes, curIndex);
 
                 curIndex += item.Count;
             }
@@ -37,12 +36,34 @@ namespace Vit.Extensions
 
 
 
-        #endregion
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static byte[] ByteDataToBytes(this List<byte[]> byteData)
+        {
+            //(x.1)get length
+            int count = 0;
+            foreach (var item in byteData)
+            {
+                count += item.Length;
+            }
 
 
+            //(x.2) copy data
+            var bytes = new byte[count];
+
+            int curIndex = 0;
+            foreach (var item in byteData)
+            {
+                if (null == item || item.Length == 0) continue;
+
+                item.CopyTo(bytes, curIndex);
+
+                curIndex += item.Length;
+            }
+            return bytes;
+        }
 
 
-        
 
     }
 }

+ 134 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/Client/ElasticSearchClient.cs

@@ -0,0 +1,134 @@
+using System.Net.Http;
+
+using Vit.Extensions;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Vit.Core.Module.Log.LogCollector.ElasticSearch.Client
+{
+    public class ElasticSearchClient
+    {
+        /// <summary>
+        /// http://192.168.20.20:9200/dev/info/_bulk
+        /// </summary>
+        string bulkUrl;
+
+
+        /// <summary>
+        /// es address, example:"http://192.168.20.20:9200"
+        /// </summary>
+        public string url;
+
+
+        /// <summary>
+        /// es index, example:"dev"
+        /// </summary>
+        public string index;
+
+        /// <summary>
+        /// es type, example:"_doc"
+        /// </summary>
+        public string type;
+
+        /// <summary>
+        /// 若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+        /// </summary>
+        public int? intervalMs; 
+
+
+
+        public void Init()
+        {
+            //信任所有的证书
+            var HttpHandler = new HttpClientHandler
+            {
+                ServerCertificateCustomValidationCallback = (a, b, c, d) => true
+            };
+            httpClient = new System.Net.Http.HttpClient(HttpHandler);
+
+            if (string.IsNullOrEmpty(type)) type = "_doc";
+            bulkUrl = url + "/" + index + "/" + type + "/_bulk";
+
+            InitTimer();
+        }
+
+
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void SendAsync(ElasticSearchRecord record)
+        {
+            if (recordList == null)
+                SendToServer(new[] { record });
+            else
+                recordList.Add(record);
+        }
+
+
+        ~ElasticSearchClient()
+        {
+            if (time != null)
+            {
+                time?.Stop();
+                time = null;
+            }
+        }
+
+
+        #region Timer
+        ConcurrentBag<ElasticSearchRecord> recordList;
+        ConcurrentBag<ElasticSearchRecord> recordList_Swap;
+        Util.Threading.Timer.SersTimer_SingleThread time;
+
+        private void InitTimer()
+        {
+            if (intervalMs.HasValue && intervalMs.Value > 0)
+            {
+                StringBuilder buffer = new StringBuilder();
+                recordList = new ConcurrentBag<ElasticSearchRecord>();
+                recordList_Swap = new ConcurrentBag<ElasticSearchRecord>();
+                time = new Util.Threading.Timer.SersTimer_SingleThread();
+                time.intervalMs = intervalMs.Value;
+                time.timerCallback = (e) =>
+                {
+                    (recordList_Swap, recordList) = (recordList, recordList_Swap);
+                    if (recordList_Swap.Count > 0)
+                    {
+                        lock(buffer)
+                             SendToServer(recordList_Swap, buffer);
+                        while (recordList_Swap.TryTake(out _)) ;
+                    }
+                };
+                time.Start();
+            }
+        }
+        #endregion
+
+
+
+        private System.Net.Http.HttpClient httpClient = null;
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        private void SendToServer(IEnumerable<ElasticSearchRecord> records, StringBuilder buffer = null)
+        {
+            var request = new HttpRequestMessage(HttpMethod.Post, bulkUrl);
+
+            if (buffer == null) buffer = new StringBuilder();
+            foreach (var record in records)
+            {
+                buffer.AppendLine("{\"create\":{}}").AppendLine(record.Serialize());
+            }
+            request.Content = new StringContent(buffer.ToString(), Vit.Core.Module.Serialization.Serialization_Newtonsoft.defaultEncoding, "application/json");
+            buffer.Clear();
+
+            // TODO:    retry when fail. 
+            //          batch:  batchIntervalInSeconds, batchSizeLimit, queueLimit
+            httpClient.SendAsync(request);
+
+
+            //var response = httpClient.SendAsync(request).Result;
+            //var body = response.Content.ReadAsStringAsync().Result;
+        }
+    }
+}

+ 57 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/Client/ElasticSearchRecord.cs

@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+
+using System;
+
+namespace Vit.Core.Module.Log.LogCollector.ElasticSearch.Client
+{
+
+    // ElasticSearch Record Format:
+    // "index": "dev", "type": "_doc"
+    /* 
+      {
+          "@timestamp":1653468236619,
+          "time": "2022-05-25T08:19:36.686Z", 
+
+          //custome object
+          "appInfo": {
+              "namespace": "mc.sers.cloud",
+              "appName": "mc",
+              "moduleName": "sers"
+              //,"...": {}
+          }
+
+          //,"...": {}
+      }
+  */
+
+    public class ElasticSearchRecord
+    {
+
+        [JsonProperty("@timestamp", NullValueHandling = NullValueHandling.Ignore)]
+        public string timestamp;
+
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string time;
+
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public object appInfo;
+
+
+        public DateTime Time 
+        {
+            set
+            {
+                //timestamp = value.ToTimeStamp();
+                timestamp = time = ToTimeString(value);
+            }
+        }
+
+
+        public static string ToTimeString(DateTime value)
+        {
+            return value.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
+        }
+    }
+}

+ 56 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/ElasticSearchCollector.cs

@@ -0,0 +1,56 @@
+using Newtonsoft.Json.Linq;
+
+using System;
+
+using Vit.Extensions;
+using System.Linq;
+using Vit.Core.Module.Log.LogCollector.ElasticSearch.Client;
+
+namespace Vit.Core.Module.Log.LogCollector.ElasticSearch
+{
+    public class ElasticSearchCollector : ILogCollector
+    {
+        public JObject config;
+        public void Init(JObject config)
+        {
+            if (config == null) return;
+
+            this.config = config;
+
+            client = config["server"]?.Deserialize<ElasticSearchClient>();
+            appInfo = config["appInfo"]?.Deserialize<object>();
+            client?.Init();
+        }
+
+        internal ElasticSearchClient client;
+        public object appInfo;
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void Write(Log.LogMessage msg)
+        {
+            var record = new LogRecord
+            {
+                Time = DateTime.UtcNow,
+                level = msg.level.ToString(),
+                message = msg.message,
+                metadata = msg.metadata,
+                appInfo = appInfo
+            };
+
+            if (record.metadata != null)
+            {
+                if (record.metadata.Length == 0)
+                    record.metadata = null;
+                else
+                {
+                    record.metadata = record.metadata.Select(m => m?.IsValueTypeOrStringType() == true ? new { value = m } : m).ToArray();
+                }
+            }
+
+            client.SendAsync(record);
+        }
+
+
+    }
+}

+ 42 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/ElasticSearch/LogRecord.cs

@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+
+using System;
+
+using Vit.Core.Module.Log.LogCollector.ElasticSearch.Client;
+
+namespace Vit.Core.Module.Log.LogCollector.ElasticSearch
+{
+    // ElasticSearch LogRecord Format:
+    // "index": "dev", "type": "_doc"
+    /* 
+    {
+      "@timestamp":1653468236619,
+      "time": "2022-05-25T08:19:36.686Z", 
+
+      "level": "info",
+      "message": "Something happened",
+      "metadata": [],
+
+      //custome object
+      "appInfo": {
+          "namespace": "mc.sers.cloud",
+          "appName": "mc",
+          "moduleName": "sers"
+          //,"...": {}
+      }
+    }
+    */
+    public class LogRecord : ElasticSearchRecord
+    {
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string level;
+
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string message;
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public Object[] metadata;
+    }
+}

+ 130 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/Client/SplunkClient.cs

@@ -0,0 +1,130 @@
+using System;
+using System.Net.Http.Headers;
+using System.Net.Http;
+
+using Vit.Extensions;
+using System.Collections.Concurrent;
+
+namespace Vit.Core.Module.Log.LogCollector.Splunk.Client
+{
+    public class SplunkClient
+    {
+
+        /// <summary>
+        /// 接口地址,如 "http://192.168.20.20:8088/services/collector"
+        /// </summary>
+        public string url;
+
+        public string authToken;
+
+        public string index;
+
+
+        /// <summary>
+        /// 若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+        /// </summary>
+        public int? intervalMs;
+
+        /// <summary>
+        /// 默认 "Splunk"
+        /// </summary>
+        public string AUTH_SCHEME;
+        /// <summary>
+        /// 默认 "X-Splunk-Request-Channel"
+        /// </summary>
+        public string SPLUNK_REQUEST_CHANNEL;
+
+
+
+
+        public void Init()
+        {
+            //信任所有的证书
+            var HttpHandler = new HttpClientHandler
+            {
+                ServerCertificateCustomValidationCallback = (a, b, c, d) => true
+            };
+            httpClient = new System.Net.Http.HttpClient(HttpHandler);
+            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AUTH_SCHEME ?? "Splunk", authToken);
+            if (!httpClient.DefaultRequestHeaders.Contains(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel"))
+            {
+                httpClient.DefaultRequestHeaders.Add(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel", Guid.NewGuid().ToString());
+            }
+
+            InitTimer();
+        }
+
+
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void SendAsync(SplunkRecord record)
+        {
+            record.index = index;
+
+            if (recordList == null)
+                SendToServer(record);
+            else
+                recordList.Add(record);
+        }
+
+
+        ~SplunkClient()
+        {
+            if (time != null)
+            {
+                time?.Stop();
+                time = null;
+            }
+        }
+
+
+        #region Timer
+        ConcurrentBag<SplunkRecord> recordList;
+        ConcurrentBag<SplunkRecord> recordList_Swap;
+        Util.Threading.Timer.SersTimer_SingleThread time;
+
+        private void InitTimer()
+        {
+            if (intervalMs.HasValue && intervalMs.Value > 0)
+            {
+                recordList = new ConcurrentBag<SplunkRecord>();
+                recordList_Swap = new ConcurrentBag<SplunkRecord>();
+                time = new Util.Threading.Timer.SersTimer_SingleThread();
+                time.intervalMs = intervalMs.Value;
+                time.timerCallback = (e) =>
+                {
+                    (recordList_Swap, recordList) = (recordList, recordList_Swap);
+                    if (recordList_Swap.Count > 0)
+                    {
+                        SendToServer(recordList_Swap);
+                        while (recordList_Swap.TryTake(out _)) ;
+                    }
+                };
+                time.Start();
+            }
+        }
+        #endregion
+
+
+
+
+
+        private System.Net.Http.HttpClient httpClient = null;
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        private void SendToServer(object record) 
+        {
+            var request = new HttpRequestMessage(HttpMethod.Post, url);
+            request.Content = new StringContent(record.Serialize(), Vit.Core.Module.Serialization.Serialization_Newtonsoft.defaultEncoding, "application/json");
+
+            // TODO:    retry when fail. 
+            //          batch:  batchIntervalInSeconds, batchSizeLimit, queueLimit
+            httpClient.SendAsync(request);
+
+            //var strMsg = record.Serialize();
+            //var response = httpClient.SendAsync(request).Result;
+            //var body = response.Content.ReadAsStringAsync().Result;
+        }
+    }
+}

+ 22 - 24
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/SplunkRecord.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/Client/SplunkRecord.cs

@@ -4,30 +4,29 @@ using System;
 
 using Vit.Extensions;
 
-namespace Vit.Core.Module.Log.LogCollector.Splunk
+namespace Vit.Core.Module.Log.LogCollector.Splunk.Client
 {
+
+    /* Splunk Record Format:
+    {
+       "time": 1426279439.123,  
+
+       "index": "dev",
+
+       "host": "localhost",
+       "source": "random-data-generator",
+       "sourcetype": "my_sample_data",
+
+       "event": { 
+          //"..."
+       }
+    }
+    */
+
+
     public class SplunkRecord
-    {/*
-             {
-                "time": 1426279439.123,  
-                "host": "localhost",
-                "source": "random-data-generator",
-                "sourcetype": "my_sample_data",
-                "index": "dev",
-                "event": { 
-                    "level": "info",
-                    "message": "Something happened",
-                    "metadata": [],
-                     //custome object
-                    "app": {
-                      "namespace": "mc.sers.cloud",
-                      "appName": "mc",
-                      "moduleName": "sers"
-                      //,"...": {}
-                    }
-                }
-             }
-             */
+    {
+
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         public double? time;
 
@@ -48,9 +47,8 @@ namespace Vit.Core.Module.Log.LogCollector.Splunk
 
 
 
-
         public DateTime Time { set => time = ToEpoch(value); }
-        
+
 
         public static double ToEpoch(DateTime value)
         {

+ 47 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/LogRecord.cs

@@ -0,0 +1,47 @@
+using Newtonsoft.Json;
+
+using System;
+
+namespace Vit.Core.Module.Log.LogCollector.Splunk
+{
+
+    /* Splunk LogRecord Format:
+    {
+       "time": 1426279439.123,  
+
+       "index": "dev",
+
+       "host": "localhost",
+       "source": "random-data-generator",
+       "sourcetype": "my_sample_data",
+
+       "event": { 
+           "level": "info",
+           "message": "Something happened",
+           "metadata": [],
+            //custome object
+           "appInfo": {
+             "namespace": "mc.sers.cloud",
+             "appName": "mc",
+             "moduleName": "sers"
+             //,"...": {}
+           }
+       }
+    }
+    */
+
+    public class LogEvent
+    {
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string level;
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string message;
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public Object[] metadata;
+
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public object appInfo;
+    }
+}

+ 0 - 59
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/SplunkClient.cs

@@ -1,59 +0,0 @@
-using System;
-using System.Net.Http.Headers;
-using System.Net.Http;
-
-using Vit.Extensions;
-
-namespace Vit.Core.Module.Log.LogCollector.Splunk
-{
-    public class SplunkClient
-    {
-
-        /// <summary>
-        /// 接口地址,如 "http://192.168.20.20:8088/services/collector"
-        /// </summary>
-        public string url;
-
-        public string authToken;
-
-
-        /// <summary>
-        /// 默认 "Splunk"
-        /// </summary>
-        public string AUTH_SCHEME;
-        /// <summary>
-        /// 默认 "X-Splunk-Request-Channel"
-        /// </summary>
-        public string SPLUNK_REQUEST_CHANNEL;
-
-
-
-       
-        public void Init()
-        {
-            httpClient = new System.Net.Http.HttpClient();
-            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AUTH_SCHEME ?? "Splunk", authToken);
-            if (!httpClient.DefaultRequestHeaders.Contains(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel"))
-            {
-                httpClient.DefaultRequestHeaders.Add(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel", Guid.NewGuid().ToString());
-            }
-        }
-
-        private System.Net.Http.HttpClient httpClient = null;
-
-
-
-        public void SendAsync(SplunkRecord record) 
-        {
-            var request = new HttpRequestMessage(HttpMethod.Post, url);
-            request.Content = new StringContent(record.Serialize(), Vit.Core.Module.Serialization.Serialization_Newtonsoft.defaultEncoding, "application/json");
-
-            // TODO:    retry when fail. 
-            //          batch:  batchIntervalInSeconds, batchSizeLimit, queueLimit
-            httpClient.SendAsync(request);
-
-            //var strMsg = msgBody.Serialize();
-            //var response = httpClient.SendAsync(request).Result;
-        }
-    }
-}

+ 20 - 66
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Splunk/SplunkCollector.cs

@@ -1,8 +1,8 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Linq;
 
 using System;
 
+using Vit.Core.Module.Log.LogCollector.Splunk.Client;
 using Vit.Extensions;
 
 namespace Vit.Core.Module.Log.LogCollector.Splunk
@@ -16,90 +16,44 @@ namespace Vit.Core.Module.Log.LogCollector.Splunk
 
             this.config = config;
 
-
-            client = config["client"]?.Deserialize<SplunkClient>();
-            message = config["message"]?.Deserialize<SplunkRecord>();
+            client = config["server"]?.Deserialize<SplunkClient>();
+            hostInfo = config["hostInfo"]?.Deserialize<SplunkRecord>();
             appInfo = config["appInfo"]?.Deserialize<object>();
             client?.Init();
         }
 
 
 
-
-        /*
-            {
-               "time": 1426279439.123,  
-               "host": "localhost",
-               "source": "random-data-generator",
-               "sourcetype": "my_sample_data",
-               "index": "dev",
-               "event": { 
-                   "level": "info",
-                   "message": "Something happened",
-                   "metadata": [],
-                    //custome object
-                   "appInfo": {
-                     "namespace": "mc.sers.cloud",
-                     "appName": "mc",
-                     "moduleName": "sers"
-                     //,"...": {}
-                   }
-               }
-            }
-            */
-
-
-        public SplunkClient client;
-        public SplunkRecord message;
+        internal SplunkClient client;
+        internal SplunkRecord hostInfo;
         public object appInfo;
 
 
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public void Write(LogMessage msg)
+        public void Write(Log.LogMessage msg)
         {
-            if (msg.metadata != null && msg.metadata.Length == 0) msg.metadata = null;
-
+            var recordEvent = new LogEvent
+            {
+                level = msg.level.ToString(),
+                message = msg.message,
+                metadata = msg.metadata,
+                appInfo = appInfo
+            };
+            if (recordEvent.metadata != null && recordEvent.metadata.Length == 0) recordEvent.metadata = null;
             var record = new SplunkRecord
             {
                 Time = DateTime.UtcNow,
-                index = message?.index,
-                host = message?.host ?? Environment.MachineName,
-                source = message?.source,
-                sourcetype = message?.sourcetype,
+                host = hostInfo?.host ?? Environment.MachineName,
+                source = hostInfo?.source,
+                sourcetype = hostInfo?.sourcetype,
 
-                @event = new Event
-                {
-                    level = msg.level.ToString(),
-                    message = msg.message,
-                    metadata = msg.metadata,
-                    appInfo = appInfo
-                }
+                @event = recordEvent
             };
 
             client.SendAsync(record);
         }
-       
-
-        public class Event
-        {
-
-            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
-            public string level;
-
-            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
-            public string message;
-
-            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
-            public object metadata;
-
-            [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
-            public object appInfo;
-        }
-
-
-
-
 
 
+ 
     }
 }

+ 39 - 11
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogCollector/Vit.Logger.appsettings.json

@@ -1,5 +1,4 @@
 {
-
   /* Vit工具配置,可不指定 */
   "Vit": {
 
@@ -10,21 +9,27 @@
       /* print the log to console. default:true  */
       "PrintToConsole": true,
 
+
+      /* print the error happened in log module to console. default:false  */
+      "PrintLogErrorToConsole": false,
+
       /* [optional]collector to send log to */
-      "//Collector": [
+      "Collector": [
         {
           /* 在此Assembly中加载类 */
           "assemblyFile": "Vit.Core.dll",
           /* 动态加载的类名,必须继承接口 Vit.Core.Module.Log.LogCollector.ILogCollector */
-          "className": "Vit.Core.Module.Log.LogCollector.Splunk.SplunkCollector",
+          //"className": "Vit.Core.Module.Log.LogCollector.Splunk.SplunkCollector",
 
-          "client": {
-            "url": "http://192.168.20.20:8088/services/collector",
-            "authToken": "xxxxx"
+          "server": {
+            "url": "https://192.168.20.20:8088/services/collector",
+            "authToken": "xxxxx",
+            "index": "dev",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
           },
 
-          "//message": {
-            "index": "dev",
+          "//hostInfo": {
             "host": "192.168.20.20:8088",
             "source": "http:mc",
             "sourcetype": "httpevent"
@@ -37,10 +42,33 @@
             "moduleName": "ServiceCenter"
             //,"...": {}
           }
+        },
+        {
+          /* 在此Assembly中加载类 */
+          "assemblyFile": "Vit.Core.dll",
+          /* 动态加载的类名,必须继承接口 Vit.Core.Module.Log.LogCollector.ILogCollector */
+          //"className": "Vit.Core.Module.Log.LogCollector.ElasticSearch.ElasticSearchCollector",
+
+          "server": {
+            // es address, example:"http://192.168.20.20:9200"
+            "url": "http://192.168.20.20:9200",
+            //es index, example:"dev"
+            "index": "dev_log",
+            //es type, example:"_doc"
+            //"type": "_doc",
+            //若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
+            "//intervalMs": 2000
+          },
+
+          //custome object
+          "appInfo": {
+            "namespace": "sers.cloud",
+            "appName": "mc",
+            "moduleName": "ServiceCenter"
+            //,"...": {}
+          }
         }
       ]
-    } 
-
+    }
   }
-
 }

+ 31 - 17
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogMng.Extensions.cs

@@ -9,22 +9,13 @@ namespace Vit.Core.Module.Log
     {
 
         #region 对外 基础
-        /// <summary>
-        /// DEBUG (调试信息):记录系统用于调试的一切信息,内容或者是一些关键数据内容的输出
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public void Debug(string message, params object[] metadata)
+        public void Info(string message)
         {
-            Log(Level.debug, message, metadata);
+            Log(Level.info, message);
         }
 
-        /// <summary>
-        /// INFO(一般信息):记录系统运行中应该让用户知道的基本信息。例如,服务开始运行,功能已经开户等。
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public void Info(string message, params object[] metadata)
         {
@@ -32,11 +23,28 @@ namespace Vit.Core.Module.Log
         }
 
 
-        /// <summary>
-        /// ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void Debug(string message)
+        {
+            Log(Level.debug, message);
+        }
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void Debug(string message, params object[] metadata)
+        {
+            Log(Level.debug, message, metadata);
+        }
+
+
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void Error(string message)
+        {
+            Log(Level.error, message);
+        }
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public void Error(string message, params object[] metadata)
         {
@@ -44,6 +52,12 @@ namespace Vit.Core.Module.Log
         }
 
 
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public void Warn(string message)
+        {
+            Log(Level.warn, message);
+        }
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public void Warn(string message, params object[] metadata)
         {

+ 1 - 1
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/LogMng.cs

@@ -25,7 +25,7 @@ namespace Vit.Core.Module.Log
 
         #region Log
 
-        static bool? PrintLogErrorToConsole = ConfigurationManager.Instance.GetByPath<bool?>("Vit.Logger.PrintLogErrorToConsole");
+        static bool? PrintLogErrorToConsole = Appsettings.json.GetByPath<bool?>("Vit.Logger.PrintLogErrorToConsole");
 
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public void Log(LogMessage msg)

+ 36 - 33
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Log/Logger.cs

@@ -22,12 +22,12 @@ namespace Vit.Core.Module.Log
         #region static Init
         static Logger()
         {
-            if (false != ConfigurationManager.Instance.GetByPath<bool?>("Vit.Logger.PrintToTxt"))
+            if (false != Appsettings.json.GetByPath<bool?>("Vit.Logger.PrintToTxt"))
             {
                 PrintToTxt = true;
             }
 
-            if (false != ConfigurationManager.Instance.GetByPath<bool?>("Vit.Logger.PrintToConsole"))
+            if (false != Appsettings.json.GetByPath<bool?>("Vit.Logger.PrintToConsole"))
             {
                 PrintToConsole = true;
             }
@@ -47,7 +47,12 @@ namespace Vit.Core.Module.Log
                 #region (x.x.2)是否内置对象
                 if (className == "SplunkCollector" || className == "Vit.Core.Module.Log.LogCollector.Splunk.SplunkCollector")
                 {
-                    return new SplunkCollector();
+                    return new LogCollector.Splunk.SplunkCollector();
+                }
+
+                if (className == "ElasticSearchCollector" || className == "Vit.Core.Module.Log.LogCollector.ElasticSearch.ElasticSearchCollector")
+                {
+                    return new LogCollector.ElasticSearch.ElasticSearchCollector();
                 }
                 #endregion
 
@@ -61,7 +66,7 @@ namespace Vit.Core.Module.Log
             #endregion
 
 
-            var configs = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<JObject[]>("Vit.Logger.Collector");
+            var configs = Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<JObject[]>("Vit.Logger.Collector");
             if (configs == null || configs.Length == 0) return;
             configs.IEnumerable_ForEach(config =>
             {
@@ -149,13 +154,12 @@ namespace Vit.Core.Module.Log
         #endregion
 
 
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static void Debug(string message)
+        {
+            log.Debug(message);
+        }
 
-
-        /// <summary>
-        /// DEBUG (调试信息):记录系统用于调试的一切信息,内容或者是一些关键数据内容的输出
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Debug(string message, params object[] metadata)
         {
@@ -163,6 +167,12 @@ namespace Vit.Core.Module.Log
         }
 
 
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static void Warn(string message)
+        {
+            log.Warn(message);
+        }
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Warn(string message, params object[] metadata)
         {
@@ -172,11 +182,13 @@ namespace Vit.Core.Module.Log
 
         #region Info
 
-        /// <summary>
-        /// INFO(一般信息):记录系统运行中应该让用户知道的基本信息。例如,服务开始运行,功能已经开户等。
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static void Info(string message )
+        {
+            log.Info(message);
+        }
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Info(string message, params object[] metadata)
         {
@@ -194,42 +206,33 @@ namespace Vit.Core.Module.Log
 
         #region Error
 
-        /// <summary>
-        /// ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
-        /// </summary>
-        /// <param name="message"></param>
-        /// <param name="metadata"></param>
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static void Error(string message)
+        {
+            log.Error(message);
+        }
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Error(string message, params object[] metadata)
         {
             log.Error(message, metadata);
         }
 
-        /// <summary>
-        /// ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
-        /// </summary>
-        /// <param name="ex"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Error(Exception ex)
         {
             log.Error(ex);
         }
 
-        /// <summary>
-        /// ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
-        /// </summary> 
-        /// <param name="message"></param>
-        /// <param name="ex"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Error(string message, Exception ex)
         {
             log.Error(message, ex);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="ssError"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static void Error(SsError ssError)
         {

+ 20 - 19
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Extensions/ObjectSerializeExtensions.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Runtime.CompilerServices;
+
 using Vit.Core.Module.Serialization;
 
 namespace Vit.Extensions
@@ -20,7 +21,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static string Serialize(this object value)
         {
-            return Serialization.Instance.SerializeToString(value);
+            return Json.SerializeToString(value);
         }
         #endregion
 
@@ -36,7 +37,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static object Deserialize(this string value, Type type)
         {
-            return Serialization.Instance.DeserializeFromString(value, type);
+            return Json.DeserializeFromString(value, type);
         }
 
         /// <summary>
@@ -48,7 +49,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static T Deserialize<T>(this string value)
         {
-            return Serialization.Instance.DeserializeFromString<T>(value);
+            return Json.DeserializeFromString<T>(value);
         }
 
         #endregion
@@ -67,7 +68,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static byte[] SerializeToBytes(this object value)
         {
-            return Serialization.Instance.SerializeToBytes(value);
+            return Json.SerializeToBytes(value);
         }
         #endregion
 
@@ -81,7 +82,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static T DeserializeFromBytes<T>(this byte[] value)
         {
-            return Serialization.Instance.DeserializeFromBytes<T>(value);
+            return Json.DeserializeFromBytes<T>(value);
         }
 
         /// <summary>
@@ -93,7 +94,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static object DeserializeFromBytes(this byte[] value, Type type)
         {
-            return Serialization.Instance.DeserializeFromBytes(value, type);
+            return Json.DeserializeFromBytes(value, type);
         }
         #endregion
 
@@ -102,7 +103,7 @@ namespace Vit.Extensions
 
         #region (x.3)object <--> ArraySegmentByte
 
-        #region SerializeToArraySegmentByte
+
         /// <summary>
         /// 
         /// </summary>
@@ -111,12 +112,12 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static ArraySegment<byte> SerializeToArraySegmentByte(this object value)
         {
-            return Serialization.Instance.SerializeToBytes(value).BytesToArraySegmentByte();
+            return Json.SerializeToArraySegmentByte(value);
         }
-        #endregion
 
 
-        #region DeserializeFromArraySegmentByte
+
+
         /// <summary>
         /// 
         /// </summary>
@@ -126,7 +127,7 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static T DeserializeFromArraySegmentByte<T>(this ArraySegment<byte> value)
         {
-            return Serialization_Newtonsoft.Instance.DeserializeFromArraySegmentByte<T>(value);
+            return Json.DeserializeFromArraySegmentByte<T>(value);
         }
 
         /// <summary>
@@ -138,12 +139,12 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static object DeserializeFromArraySegmentByte(this ArraySegment<byte> value, Type type)
         {
-            return Serialization_Newtonsoft.Instance.DeserializeFromArraySegmentByte(value, type);
+            return Json.DeserializeFromArraySegmentByte(value, type);
         }
-        #endregion
+
         #endregion
 
-               
+
 
 
 
@@ -160,8 +161,8 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static object ConvertBySerialize(this object value, Type type)
         {
-            var str = Serialization.Instance.SerializeToString(value);
-            return Serialization.Instance.DeserializeFromString(str, type); 
+            var str = Json.SerializeToString(value);
+            return Json.DeserializeFromString(str, type);
         }
 
         /// <summary>
@@ -173,13 +174,13 @@ namespace Vit.Extensions
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static TTarget ConvertBySerialize<TTarget>(this object value)
         {
-            var str = Serialization.Instance.SerializeToString(value);
-            return Serialization.Instance.DeserializeFromString<TTarget>(str);
+            var str = Json.SerializeToString(value);
+            return Json.DeserializeFromString<TTarget>(str);
         }
         #endregion
 
 
-       
+
 
 
 

+ 53 - 3
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/ISerialization.cs

@@ -7,12 +7,37 @@ namespace Vit.Core.Module.Serialization
 
         #region (x.1)object <--> String
 
+        /// <summary>
+        /// T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="value"></param>
+        /// <returns></returns>
         string SerializeToString<T>(T value);
+
+        /// <summary>
+        /// T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
         string SerializeToString(object value, Type type);
 
 
 
+        /// <summary>
+        /// 使用Newtonsoft反序列化。T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>    
+        /// <returns></returns>
         T DeserializeFromString<T>(string value);
+
+        /// <summary>
+        /// 使用Newtonsoft反序列化。T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
         object DeserializeFromString(string value, Type type);
 
         #endregion
@@ -21,18 +46,43 @@ namespace Vit.Core.Module.Serialization
 
         #region (x.2)object <--> bytes
 
+        /// <summary>
+        /// T 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="obj"></param>
+        /// <returns></returns>
         byte[] SerializeToBytes<T>(T obj);
-        byte[] SerializeToBytes(object value, Type type);
 
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        byte[] SerializeToBytes(object value, Type type);
 
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="bytes"></param>
+        /// <returns></returns>
         T DeserializeFromBytes<T>(byte[] bytes);
+
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <param name="bytes"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
         object DeserializeFromBytes(byte[] bytes, Type type);
 
         #endregion
 
 
 
-        #region (x.3)DeserializeFromSpan
+        #region (x.3)object <--> Span
 
         //T DeserializeFromSpan<T>(ReadOnlyMemory<byte> bytes);
 
@@ -42,7 +92,7 @@ namespace Vit.Core.Module.Serialization
 
 
 
-        #region (x.4)DeserializeFromArraySegmentByte
+        #region (x.4)object <--> ArraySegmentByte
 
         T DeserializeFromArraySegmentByte<T>(ArraySegment<byte> bytes);
 

+ 166 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Json.cs

@@ -0,0 +1,166 @@
+
+using System;
+using System.Runtime.CompilerServices;
+
+using Vit.Extensions;
+
+namespace Vit.Core.Module.Serialization
+{
+    public static class Json
+    {
+
+        public static ISerialization Instance { get; set; } = Serialization_Newtonsoft.Instance;
+
+
+        #region (x.1)object <--> String
+
+        /// <summary>
+        /// T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static string SerializeToString<T>(T value)
+        {
+            return Instance.SerializeToString<T>(value);
+        }
+
+        /// <summary>
+        /// T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static string SerializeToString(object value, Type type)
+        {
+            return Instance.SerializeToString(value, type);
+        }
+
+
+
+        /// <summary>
+        /// 使用Newtonsoft反序列化。T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>    
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T DeserializeFromString<T>(string value)
+        {
+            return Instance.DeserializeFromString<T>(value);
+        }
+
+        /// <summary>
+        /// 使用Newtonsoft反序列化。T也可为值类型(例如 int?、bool) 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static object DeserializeFromString(string value, Type type)
+        {
+            return Instance.DeserializeFromString(value, type);
+        }
+
+        #endregion
+
+
+
+        #region (x.2)object <--> bytes
+
+        /// <summary>
+        /// T 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static byte[] SerializeToBytes<T>(T obj)
+        {
+            return Instance.SerializeToBytes<T>(obj);
+        }
+
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static byte[] SerializeToBytes(object value, Type type)
+        {
+            return Instance.SerializeToBytes(value, type);
+        }
+
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="bytes"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T DeserializeFromBytes<T>(byte[] bytes)
+        {
+            return Instance.DeserializeFromBytes<T>(bytes);
+        }
+
+        /// <summary>
+        /// type 可以为   byte[]、string、 object 、struct
+        /// </summary>
+        /// <param name="bytes"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static object DeserializeFromBytes(byte[] bytes, Type type)
+        {
+            return Instance.DeserializeFromBytes(bytes, type);
+        }
+
+        #endregion
+
+
+
+        #region (x.3)object <--> Span
+
+        //T DeserializeFromSpan<T>(ReadOnlyMemory<byte> bytes);
+
+        //object DeserializeFromSpan(ReadOnlyMemory<byte> bytes, Type type);
+
+        #endregion
+
+
+
+        #region (x.4)object <--> ArraySegmentByte
+
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ArraySegment<byte> SerializeToArraySegmentByte(this object value)
+        {
+            return Instance.SerializeToBytes(value).BytesToArraySegmentByte();
+        }
+
+
+
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T DeserializeFromArraySegmentByte<T>(ArraySegment<byte> bytes)
+        {
+            return Instance.DeserializeFromArraySegmentByte<T>(bytes);
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static object DeserializeFromArraySegmentByte(ArraySegment<byte> bytes, Type type)
+        {
+            return Instance.DeserializeFromArraySegmentByte(bytes, type);
+        }
+
+        #endregion
+
+    }
+}

+ 20 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Obsolete/Serialization.cs

@@ -0,0 +1,20 @@
+
+
+
+using System;
+
+namespace Vit.Core.Module.Serialization
+{
+    /// <summary>
+    /// please use Vit.Core.Module.Serialization.Json instead
+    /// </summary>
+    [Obsolete("use Vit.Core.Module.Serialization.Json instead")]
+    public class Serialization
+    {
+        /// <summary>
+        /// please use Vit.Core.Module.Serialization.Json.Instance instead
+        /// </summary>
+        [Obsolete("use Vit.Core.Module.Serialization.Json.Instance instead")]
+        public static ISerialization Instance => Json.Instance;
+    }
+}

+ 0 - 12
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Serialization.cs

@@ -1,12 +0,0 @@
- 
-
-
-namespace Vit.Core.Module.Serialization
-{
-    public  abstract class Serialization
-    {
-
-        public static ISerialization Instance { get; set; } = Serialization_Newtonsoft.Instance;
-
-    }
-}

+ 9 - 6
dotnet/Library/Vit/Vit.Core/Vit.Core/Module/Serialization/Serialization_Newtonsoft.cs

@@ -12,7 +12,7 @@ namespace Vit.Core.Module.Serialization
     {
         #region defaultEncoding
         public static Encoding defaultEncoding { get; set; } =
-            ConfigurationManager.Instance.GetByPath<string>("Vit.Serialization.Encoding")?.StringToEnum<EEncoding>().ToEncoding() ?? Encoding.UTF8;
+            Appsettings.json.GetByPath<string>("Vit.Serialization.Encoding")?.StringToEnum<EEncoding>().ToEncoding() ?? Encoding.UTF8;
 
         #endregion
 
@@ -128,7 +128,7 @@ namespace Vit.Core.Module.Serialization
             serializeSetting.Formatting = Formatting.None;
 
             //日期格式化
-            var DateTimeFormat = ConfigurationManager.Instance.GetByPath<string>("Vit.Serialization.DateTimeFormat")
+            var DateTimeFormat = Appsettings.json.GetByPath<string>("Vit.Serialization.DateTimeFormat")
                 ?? "yyyy-MM-dd HH:mm:ss";
 
             serializeSetting.DateFormatHandling = global::Newtonsoft.Json.DateFormatHandling.IsoDateFormat;
@@ -200,10 +200,12 @@ namespace Vit.Core.Module.Serialization
 
             Type type = typeof(T);
 
+            if (type.GetUnderlyingTypeIfNullable().IsEnum)
+                return value.StringToEnum<T>();
+
             if (type.TypeIsValueTypeOrStringType())
-            {
                 return (T)DeserializeStruct(value, type);
-            }
+
 
             //if (string.IsNullOrWhiteSpace(value)) return type.DefaultValue();
 
@@ -222,10 +224,11 @@ namespace Vit.Core.Module.Serialization
         {
             if (null == value || null == type) return null;
 
+            if (type.GetUnderlyingTypeIfNullable().IsEnum)
+                return value.StringToEnum(type);
+
             if (type.TypeIsValueTypeOrStringType())
-            {
                 return DeserializeStruct(value, type);
-            }
 
             //if (string.IsNullOrWhiteSpace(value)) return type.DefaultValue();
 

+ 34 - 43
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/ApiReturn.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/ApiReturn.cs

@@ -1,4 +1,5 @@
-using System;  
+using System;
+
 using Vit.Core.Util.ComponentModel.Model;
 
 namespace Vit.Core.Util.ComponentModel.Data
@@ -6,7 +7,7 @@ namespace Vit.Core.Util.ComponentModel.Data
     public class ApiReturn
     {
         /// <summary>
-        /// 构建成功的返回数据
+        /// construct with success result
         /// </summary>
         public ApiReturn()
         {
@@ -19,55 +20,51 @@ namespace Vit.Core.Util.ComponentModel.Data
 
 
         /// <summary>
-        /// 构造失败的返回数据
+        /// construct with error result
         /// </summary>
         /// <param name="errorCode"></param>
         /// <param name="errorMessage"></param>
-        /// <param name="errorTag">自定义ErrorTag格式。每处ErrorTag建议唯一。建议格式为 日期_作者缩写_自定义序号,例如:"150721_lith_1"</param>
+        /// <param name="errorTag">demo: "150721_lith_1"</param>
         /// <param name="errorDetail"></param>
-        public ApiReturn(int? errorCode = null, string errorMessage = null, string errorTag = null, Newtonsoft.Json.Linq.JObject errorDetail = null)
+        public ApiReturn(int? errorCode = null, string errorMessage = null, string errorTag = null, object errorDetail = null)
         {
             success = false;
-            error = new SsError.SsError (errorCode, errorMessage, errorTag, errorDetail);
+            error = new SsError.SsError(errorCode, errorMessage, errorTag, errorDetail);
         }
 
 
 
         /// <summary>
-        /// 是否成功
+        /// whether success
         /// </summary>
         [SsExample("true")]
-        [SsDescription("是否成功")]
-        public bool success=true;
+        [SsDescription("whether success")]
+        public bool success = true;
 
         /// <summary>
-        /// 错误信息
+        /// error info
         /// </summary>
         [Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
-        [SsDescription("错误信息")]
+        [SsDescription("error info")]
         public SsError.SsError error;
 
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="error"></param>
+
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public static implicit operator ApiReturn(SsError.SsError error)
+        public static implicit operator ApiReturn(bool success)
         {
-            return new ApiReturn() { success = false, error = error };
+            return new ApiReturn(success);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="success"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public static implicit operator ApiReturn(bool success)
+        public static implicit operator ApiReturn(SsError.SsError error)
         {
-            return new ApiReturn(success);
+            return new ApiReturn() { success = false, error = error };
         }
 
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static implicit operator ApiReturn(Exception ex)
         {
@@ -78,27 +75,21 @@ namespace Vit.Core.Util.ComponentModel.Data
     }
 
 
-    public class ApiReturn<T>: ApiReturn
+    public class ApiReturn<T> : ApiReturn
     {
-
         public ApiReturn() { }
 
         public ApiReturn(T data) { this.data = data; }
 
 
         /// <summary>
-        /// 数据
+        /// data
         /// </summary>
-        [SsDescription("数据")]
+        [SsDescription("data")]
         public T data;
 
 
 
-
-        /// <summary>
-        /// 隐式转换
-        /// </summary>
-        /// <param name="value"></param>
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static implicit operator ApiReturn<T>(T value)
         {
@@ -106,24 +97,24 @@ namespace Vit.Core.Util.ComponentModel.Data
         }
 
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="error"></param>
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static implicit operator ApiReturn<T>(bool success)
+        {
+            return new ApiReturn<T>() { success = success };
+        }
+
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static implicit operator ApiReturn<T>(SsError.SsError error)
         {
-            return new ApiReturn<T>(){ success = false, error = error };
+            return new ApiReturn<T>() { success = false, error = error };
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="success"></param>
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public static implicit operator ApiReturn<T>(bool success)
+        public static implicit operator ApiReturn<T>(Exception ex)
         {
-            return new ApiReturn<T>() { success=success};
+            return (SsError.SsError)ex;
         }
     }
 }

+ 36 - 19
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/SsError/Extensions/ExceptionExtensions.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/Exception_Extensions.cs

@@ -1,11 +1,11 @@
 using System;
-using Newtonsoft.Json.Linq;
+
+using Vit.Core.Util.ComponentModel.Data;
 using Vit.Core.Util.ComponentModel.SsError;
-using Vit.Extensions;
 
 namespace Vit.Extensions
 {
-    public static partial class ExceptionExtensions 
+    public static partial class Exception_Extensions 
     {
         #region Data
 
@@ -156,33 +156,50 @@ namespace Vit.Extensions
         {
             return ex.ErrorDetail_Get<object>();
         }
-        #endregion     
+        #endregion
 
 
 
-        #region SsError
-        /// <summary>
-        /// SsError
-        /// </summary>
-        /// <param name="ex"></param>
-        /// <param name="ssError"></param>
-        /// <returns></returns>
+        #region SetSsError
+
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
-        public static Exception SsError_Set(this Exception ex, SsError ssError)
+        public static Exception SetSsError(this Exception ex, SsError error)
         {
-            ssError?.SetErrorToException(ex);
+            if (ex != null && error != null)
+            {
+                if (null != error.errorCode) ex.ErrorCode_Set(error.errorCode);
+                if (null != error.errorMessage) ex.ErrorMessage_Set(error.errorMessage);
+                if (null != error.errorTag) ex.ErrorTag_Set(error.errorTag);
+                if (null != error.errorDetail) ex.ErrorDetail_Set(error.errorDetail);
+            }
             return ex;
         }
+        #endregion
+
+        #region ToSsError
 
-        /// <summary>
-        /// SsError
-        /// </summary>
-        /// <param name="ex"></param>
-        /// <returns></returns>
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public static SsError ToSsError(this Exception ex)
         {
-            return new SsError().LoadFromException(ex);
+            return new SsError(ex);
+        }
+        #endregion
+
+
+        #region ToApiReturn
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static ApiReturn ToApiReturn(this Exception ex)
+        {
+            return new SsError(ex);
+        }
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static ApiReturn<T> ToApiReturn<T>(this Exception ex)
+        {
+            return new SsError(ex);
         }
         #endregion
 

+ 0 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/SsError/SsError.Const.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError.Const.cs


+ 18 - 18
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/SsError/SsError.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError.cs

@@ -1,6 +1,8 @@
 using System;
+
 using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+
+using Vit.Core.Util.ComponentModel.Data;
 using Vit.Core.Util.ComponentModel.Model;
 using Vit.Extensions;
 
@@ -22,9 +24,9 @@ namespace Vit.Core.Util.ComponentModel.SsError
         /// </summary>
         /// <param name="errorCode"></param>
         /// <param name="errorMessage"></param>
-        /// <param name="errorTag">自定义ErrorTag格式。每处ErrorTag建议唯一。建议格式为 日期_作者缩写_自定义序号,例如:"150721_lith_1"</param>
+        /// <param name="errorTag">demo: "150721_lith_1"</param>
         /// <param name="errorDetail"></param>
-        public SsError(int? errorCode = null, string errorMessage = null, string errorTag = null, JObject errorDetail=null)
+        public SsError(int? errorCode = null, string errorMessage = null, string errorTag = null, object errorDetail = null)
         {
             this.errorCode = errorCode;
             this.errorMessage = errorMessage;
@@ -46,26 +48,25 @@ namespace Vit.Core.Util.ComponentModel.SsError
         /// 
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
-        [SsExample("操作出现异常")]
+        [SsExample("error occurred in the operation")]
         public string errorMessage { get; set; }
 
 
         /// <summary>
-        /// 自定义ErrorTag格式。每处ErrorTag建议唯一。建议格式为 日期_作者缩写_自定义序号,例如:"150721_lith_1"
+        /// demo: "150721_lith_1"
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         [SsExample("150721_lith_1")]
-        [SsDescription("自定义ErrorTag格式。每处ErrorTag建议唯一。建议格式为 日期_作者缩写_自定义序号,例如:\"150721_lith_1\"")]
         public string errorTag { get; set; }
 
 
 
         /// <summary>
-        /// 错误详情(json类型)
+        /// errorDetail(json)
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         [SsExample("{}")]
-        [SsDescription("错误详情(json类型)")]
+        [SsDescription("errorDetail(json)")]
         public object errorDetail { get; set; }
 
 
@@ -73,21 +74,20 @@ namespace Vit.Core.Util.ComponentModel.SsError
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public virtual SsError LoadFromException(Exception ex)
         {
-            errorCode = ex.ErrorCode_Get();
-            errorMessage = ex.ErrorMessage_Get();
-            errorTag = ex.ErrorTag_Get();
-            errorDetail = ex.ErrorDetail_Get();
+            if (ex != null)
+            {
+                errorCode = ex.ErrorCode_Get();
+                errorMessage = ex.ErrorMessage_Get();
+                errorTag = ex.ErrorTag_Get();
+                errorDetail = ex.ErrorDetail_Get();
+            }
             return this;
         }
 
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
         public virtual Exception SetErrorToException(Exception ex)
         {
-            if (null != errorCode) ex.ErrorCode_Set(errorCode);
-            if (null != errorMessage) ex.ErrorMessage_Set(errorMessage);
-            if (null != errorTag) ex.ErrorTag_Set(errorTag);
-            if (null != errorDetail) ex.ErrorDetail_Set(errorDetail);            
-            return ex;
+            return ex.SetSsError(this);
         }
 
 
@@ -96,6 +96,6 @@ namespace Vit.Core.Util.ComponentModel.SsError
         public static implicit operator SsError(Exception ex)
         {
            return new SsError().LoadFromException(ex);
-        }
+        } 
     }
 }

+ 36 - 0
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/ApiReturn/SsError_Extensions.cs

@@ -0,0 +1,36 @@
+using System;
+
+using Vit.Core.Util.ComponentModel.Data;
+using Vit.Core.Util.ComponentModel.SsError;
+
+namespace Vit.Extensions
+{
+    public static partial class SsError_Extensions
+    {
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static Exception ToException(this SsError data, string defaultMessage = null)
+        {
+            var ex = new Exception(data?.errorMessage ?? defaultMessage ?? "Error");
+            data?.SetErrorToException(ex);
+            return ex;
+        }
+
+
+
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static ApiReturn ToApiReturn(this SsError data)
+        {
+            ApiReturn apiRet = data;
+            return apiRet;
+        }
+
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+        public static ApiReturn<T> ToApiReturn<T>(this SsError data)
+        {
+            ApiReturn<T> apiRet = data;
+            return apiRet;
+        }
+
+    }
+}

+ 4 - 4
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/PageData.cs

@@ -24,18 +24,18 @@ namespace Vit.Core.Util.ComponentModel.Data
         }
 
         /// <summary>
-        /// 数据
+        /// rows
         /// </summary>
-        [SsDescription("数据")]
+        [SsDescription("rows")]
         public List<T> rows;
 
 
         /// <summary>
-        /// 总数据个数
+        /// totalCount
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         [SsExample("1000")]
-        [SsDescription("总数据个数")]
+        [SsDescription("totalCount")]
         public int totalCount;
     }
 }

+ 4 - 4
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/PageInfo.cs

@@ -6,19 +6,19 @@ namespace Vit.Core.Util.ComponentModel.Data
     public class PageInfo
     {
         /// <summary>
-        /// 每页数据条数
+        /// pageSize
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         [SsExample("10")]
-        [SsDescription("每页数据条数")]
+        [SsDescription("pageSize")]
         public int pageSize;
 
         /// <summary>
-        /// 页码,从1开始
+        /// pageIndex, starting from 1
         /// </summary>
         [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
         [SsExample("1")]
-        [SsDescription("页码,从1开始")]
+        [SsDescription("pageIndex, starting from 1")]
         public int pageIndex;     
        
     }

+ 4 - 4
dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Query/SortItem.cs → dotnet/Library/Vit/Vit.Core/Vit.Core/Util/ComponentModel/Data/SortItem.cs

@@ -5,17 +5,17 @@ namespace Vit.Core.Util.ComponentModel.Query
     public class SortItem
     {
         /// <summary>
-        /// 字段名(可多级,例如 "parent.name")
+        /// field name(can be cascaded). demo "parent.id"
         /// </summary>
         [SsExample("id")]
-        [SsDescription("字段名(可多级,例如 \"parent.name\")")]
+        [SsDescription("field name(can be cascaded). demo \"parent.id\"")]
         public string field;
 
         /// <summary>
-        /// 是否为正向排序
+        /// whether is order by ascendin
         /// </summary>
         [SsExample("true")]
-        [SsDescription("是否为正向排序")]
+        [SsDescription("whether is order by ascending")]
         public bool asc;
     }
 }

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.