This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-rover.git


The following commit(s) were added to refs/heads/main by this push:
     new 357cca0  Add the Agent Sensor scanner (#15)
357cca0 is described below

commit 357cca07cd0b5c00354c7ba8aa00f27d0d8dc0be
Author: mrproliu <[email protected]>
AuthorDate: Mon Apr 18 20:15:10 2022 +0800

    Add the Agent Sensor scanner (#15)
---
 .github/workflows/rover.yaml                       |   3 +
 configs/rover_configs.yaml                         |  27 ++-
 docs/README.md                                     |   2 +-
 docs/en/{guide => guides}/README.md                |   0
 .../en/{guide => guides}/compile/how-to-compile.md |   0
 .../contribution/how-to-write-module.md            |   0
 .../setup/configuration/process_discovery/linux.md |  68 ------
 .../configuration/process_discovery/overview.md    |   2 +-
 .../configuration/process_discovery/scanner.md     |  97 ++++++++
 .../en/setup/examples/cases/agent-sensor/readme.md |  50 ++++
 .../examples/cases/profiling-process/readme.md     |  14 +-
 docs/en/setup/overview.md                          |   1 +
 docs/menu.yml                                      |   2 +
 pkg/process/api/process.go                         |  10 +-
 pkg/process/config.go                              |   6 +-
 pkg/process/finders/base/config.go                 |   2 -
 pkg/process/finders/base/finder.go                 |   2 +
 pkg/process/finders/manager.go                     |   6 +-
 pkg/process/finders/register.go                    |   4 +-
 pkg/process/finders/{vm => scanner}/config.go      |  35 ++-
 pkg/process/finders/{vm => scanner}/finder.go      | 267 ++++++++++++++++++---
 pkg/process/finders/{vm => scanner}/process.go     |  51 +++-
 pkg/process/finders/{vm => scanner}/template.go    |   2 +-
 pkg/process/finders/storage.go                     |  10 +-
 pkg/process/module.go                              |   2 +-
 test/e2e/base/base-compose.yml                     |  15 +-
 test/e2e/base/env                                  |   2 +
 .../agent_sensor/golang/Dockerfile.go2sky}         |  23 +-
 .../cases/agent_sensor/golang/docker-compose.yml   |  60 +++++
 test/e2e/cases/agent_sensor/golang/e2e.yaml        |  42 ++++
 .../agent_sensor/golang/expected/instance.yml}     |  21 +-
 .../agent_sensor/golang/expected/process.yml}      |  23 +-
 .../agent_sensor/golang/expected/service.yml}      |  10 +-
 33 files changed, 692 insertions(+), 167 deletions(-)

diff --git a/.github/workflows/rover.yaml b/.github/workflows/rover.yaml
index 4b68061..abe1c15 100644
--- a/.github/workflows/rover.yaml
+++ b/.github/workflows/rover.yaml
@@ -79,6 +79,9 @@ jobs:
             config: test/e2e/cases/profiling/c++/e2e.yaml
           - name: C Profiling
             config: test/e2e/cases/profiling/c/e2e.yaml
+
+          - name: go2sky Agent Sensor
+            config: test/e2e/cases/agent_sensor/golang/e2e.yaml
     steps:
       - uses: actions/checkout@v2
         with:
diff --git a/configs/rover_configs.yaml b/configs/rover_configs.yaml
index 9636fa6..931c3d2 100644
--- a/configs/rover_configs.yaml
+++ b/configs/rover_configs.yaml
@@ -37,30 +37,33 @@ core:
 process_discovery:
   # The period of report or keep alive process(second)
   heartbeat_period: ${ROVER_PROCESS_DISCOVERY_HEARTBEAT_PERIOD:20s}
-  # Detect processes in VM mode
-  vm:
-    # Is active the VM mode to detect processes
-    active: ${ROVER_PROCESS_DISCOVERY_VM_ACTIVE:false}
+  # Scan process from linux
+  scanner:
     # The period to detect the process
-    period: ${ROVER_PROCESS_DISCOVERY_VM_PERIOD:3s}
-    finders:
+    period: ${ROVER_PROCESS_DISCOVERY_SCAN_PERIOD:3s}
+    # The process detection modes of the scanner. Support "REGEX", 
"AGENT_SENSOR"
+    mode: ${ROVER_PROCESS_DISCOVERY_SCAN_MODE:AGENT_SENSOR}
+    agent:
+      # Supports scanning for how long ago of the active agent
+      process_status_refresh_period: 
${ROVER_PROCESS_DISCOVERY_AGENT_PROCESS_STATUS_REFRESH_PERIOD:1m}
+    regex:
       # Use regex string to locate the processes
       # Duplicate entities cannot be reported. If multiple entity are 
generated, only one process will be report
       # If the multiple finders could match the same one process, only the 
first finder could be selected and report
-      - match_cmd_regex: ${ROVER_PROCESS_DISCOVERY_VM_FINDER_MATCH_CMD_REGEX:}
+      - match_cmd: ${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_MATCH_CMD:}
         # The Layer need to relate to the process entity
-        layer: ${ROVER_PROCESS_DISCOVERY_VM_FINDER_LAYER:OS_LINUX}
+        layer: ${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LAYER:OS_LINUX}
         # The Service Name need to relate to the process entity
-        service_name: ${ROVER_PROCESS_DISCOVERY_VM_FINDER_SERVICE_NAME:}
+        service_name: ${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_SERVICE_NAME:}
         # The Service Instance Name need to relate to the process entity
         # By default the instance name is the host IP v4 address from "en0" 
net interface
-        instance_name: 
${ROVER_PROCESS_DISCOVERY_VM_FINDER_INSTANCE_NAME:{{.Rover.HostIPV4 "en0"}}}
+        instance_name: 
${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_INSTANCE_NAME:{{.Rover.HostIPV4 "en0"}}}
         # The Process Name need to relate to the process entity
         # By default, the process name is the executable name of the process
-        process_name: 
${ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_NAME:{{.Process.ExeName}}}
+        process_name: 
${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_PROCESS_NAME:{{.Process.ExeName}}}
         # The Process Labels, used to aggregate similar process from service 
entity
         # Multiple labels split by ","
-        labels: ${ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_LABELS:}
+        labels: ${ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LABELS:}
 
 profiling:
   # Is active the process profiling
diff --git a/docs/README.md b/docs/README.md
index 9a8fa1d..578fa55 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -7,7 +7,7 @@ From here you can learn all about **SkyWalking Rover's** 
architecture, and how t
 
 - [Setup](en/setup/overview.md). Introduce how to set up the SkyWalking Rover.
 
-- [Guides](en/guide/README.md). Guide users to develop or debug SkyWalking 
Rover.
+- [Guides](en/guides/README.md). Guide users to develop or debug SkyWalking 
Rover.
 
 We're always looking for help to improve our documentation and codes, so 
please don’t hesitate to [file an 
issue](https://github.com/apache/skywalking/issues/new)
 if you see any problem.
diff --git a/docs/en/guide/README.md b/docs/en/guides/README.md
similarity index 100%
rename from docs/en/guide/README.md
rename to docs/en/guides/README.md
diff --git a/docs/en/guide/compile/how-to-compile.md 
b/docs/en/guides/compile/how-to-compile.md
similarity index 100%
rename from docs/en/guide/compile/how-to-compile.md
rename to docs/en/guides/compile/how-to-compile.md
diff --git a/docs/en/guide/contribution/how-to-write-module.md 
b/docs/en/guides/contribution/how-to-write-module.md
similarity index 100%
rename from docs/en/guide/contribution/how-to-write-module.md
rename to docs/en/guides/contribution/how-to-write-module.md
diff --git a/docs/en/setup/configuration/process_discovery/linux.md 
b/docs/en/setup/configuration/process_discovery/linux.md
deleted file mode 100644
index a66bdac..0000000
--- a/docs/en/setup/configuration/process_discovery/linux.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Linux Process Detector
-
-The Linux process detector could detect any process in the Linux with finders.
-Each finder could define a regex to filter which processes declare to 
monitored, and the metadata of the process when the report to the backend.
-
-## Configuration
-
-| Name | Default | Environment Key | Description |
-|------|---------|-----------------|-------------|
-| process_discovery.vm.active | false | ROVER_PROCESS_DISCOVERY_VM_ACTIVE | Is 
active the VM mode to detect processes. |
-| process_discovery.vm.period | 3s | ROVER_PROCESS_DISCOVERY_VM_PERIOD | The 
period to detect the process. |
-| process_discovery.vm.finders | | | It could be define multiple finders to 
find the process. It only provide one finder by default. |
-| process_discovery.vm.finders.match_cmd_regex | | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_MATCH_CMD_REGEX | Use regex string to locate 
the process from the command line of the process. |
-| process_discovery.vm.finders.layer | OS_LINUX | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_LAYER | The Layer of the process entity |
-| process_discovery.vm.finders.service_name | | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_SERVICE_NAME | The Service Name of the 
process entity. |
-| process_discovery.vm.finders.instance_name | {{.Rover.HostIPV4 "en0"}} | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_INSTANCE_NAME | The Service Instance Name of 
the process entity, by default, the instance name is the host IP v4 address 
from "en0" net interface. |
-| process_discovery.vm.finders.process_name | {{.Process.ExeName}} | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_NAME | The Process Name of the 
process entity, by default, the process name is the executable name of the 
process. |
-| process_discovery.vm.finders.labels | | 
ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_LABELS | The Process Labels, used to 
aggregate similar process from service entity. Multiple labels split by ",". |
-
-### Note
-
-The duplicate processes entities cannot be reported. If multiple entities are 
generated, only one process will be reported.
-If the multiple finders could match the same process, only the first finder 
could be selected and reported.
-
-## Entity Builder
-
-The metadata of the process could build by the Go Template to help dynamically 
build them, also, you could just configure it as the string value, and it still 
works.
-
-These fields are supported using template to build:
-1. Service Name
-2. Service Instance Name
-3. Process NAme
-
-### Context
-
-The context provides multiple functions for helping you build the process 
metadata.
-
-#### Rover
-
-Rover context provides the context of the rover process instance and VM data.
-
-| Name | Argument |  Example  | Description |
-|------|--------- |-----------|-------------|
-| InstanceID | None | `{{.Rover.InstanceID}}` | Get the Instance ID of the 
rover. |
-| HostIPV4 | The Interface name | `{{.Rover.HostIPV4 "en0"}}` | Get the ipv4 
address from the appointed network interface name. |
-| HostIPV6 | The Interface name | `{{.Rover.HostIPV6 "en0"}}` | Get the ipv6 
address from the appointed network interface name. |
-| HostName | None | `{{.Rover.HostName}}` | Get the host name of current 
machine.|
-
-#### Finder
-
-Finder context provides the context of the current process finder.
-
-| Name | Argument |  Example  | Description |
-|------|--------- |-----------|-------------|
-| Layer | None | `{{.Finder.Layer}}` | The layer of the current process which 
defines in the configuration | 
-| RegexMatchGroup | The index of the regex pattern | 
`{{.Finder.RegexMatchGroup 1}}`| When using the regex to match the process 
command line, it could use the group concept in the regex. This function could 
help you get the group value from it. |
-
-#### Process
-
-Process context provides the context relate to which process is matched.
-
-| Name | Argument |  Example  | Description |
-|------|--------- |-----------|-------------|
-| ExeFilePath | None | `{{.Process.ExeFilePath}}` | The execute file path of 
process. |
-| ExeName | None | `{{.Process.ExeName}}` | The execute file name. |
-| CommandLine | None | `{{.Process.CommandLine}}` | The command line of 
process. |
-| Pid | None | `{{.Process.Pid}}` | The id of the process. |
-| WorkDir | None | `{{.Process.WorkDir}}` | The work directory path of the 
process. |
\ No newline at end of file
diff --git a/docs/en/setup/configuration/process_discovery/overview.md 
b/docs/en/setup/configuration/process_discovery/overview.md
index 0c09963..35fd845 100644
--- a/docs/en/setup/configuration/process_discovery/overview.md
+++ b/docs/en/setup/configuration/process_discovery/overview.md
@@ -12,4 +12,4 @@ After the process upload is completed, the other modules 
could perform more oper
 ## Process Detector
 
 Process Detector is used to detect the process from the VM with the different 
environment:
-1. [Linux Process Detector](./linux.md)
\ No newline at end of file
+1. [Linux Process Scanner](./scanner.md)
\ No newline at end of file
diff --git a/docs/en/setup/configuration/process_discovery/scanner.md 
b/docs/en/setup/configuration/process_discovery/scanner.md
new file mode 100644
index 0000000..af2c3e7
--- /dev/null
+++ b/docs/en/setup/configuration/process_discovery/scanner.md
@@ -0,0 +1,97 @@
+# Linux Process Detector
+
+The Linux process scanner could detect any process in the Linux with finders. 
It has two mode:
+1. **REGEX**: could define a regex to filter which processes declare to 
monitor.
+2. **AGENT_SENSOR**: scan recent active agent which have process status hook.
+
+After find the process, it would be collect the metadata of the process when 
the report to the backend.
+
+## Configuration
+
+| Name | Default | Environment Key | Description |
+|------|---------|-----------------|-------------|
+| process_discovery.scanner.period | 3s | ROVER_PROCESS_DISCOVERY_SCAN_PERIOD 
| The period to detect the process. |
+| process_discovery.scanner.mode | AGENT_SENSOR | 
ROVER_PROCESS_DISCOVERY_SCAN_MODE | The process detection modes of the scanner. 
Support "REGEX", "AGENT_SENSOR". |
+| process_discovery.scanner.agent | | | Active when using the "AGENT_SENSOR" 
mode scanner. |
+| process_discovery.scanner.agent.process_status_refresh_period | 1m | 
ROVER_PROCESS_DISCOVERY_AGENT_PROCESS_STATUS_REFRESH_PERIOD | Supports scanning 
for how long ago of the active agent. |
+| process_discovery.scanner.regex | | | Active when using the "REGEX" mode 
scanner, it supports using multiple regex to matches difference processes. |
+| process_discovery.scanner.regex.match_cmd | | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_MATCH_CMD | Use regex string to locate 
the process from the command line of the process. |
+| process_discovery.scanner.regex.layer | OS_LINUX | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LAYER | The Layer of the process entity |
+| process_discovery.scanner.regex.service_name | | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_SERVICE_NAME | The Service Name of the 
process entity. |
+| process_discovery.scanner.regex.instance_name | {{.Rover.HostIPV4 "en0"}} | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_INSTANCE_NAME | The Service Instance Name 
of the process entity, by default, the instance name is the host IP v4 address 
from "en0" net interface. |
+| process_discovery.scanner.regex.process_name | {{.Process.ExeName}} | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_PROCESS_NAME | The Process Name of the 
process entity, by default, the process name is the executable name of the 
process. |
+| process_discovery.scanner.regex.labels | | 
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LABELS | The Process Labels, used to 
aggregate similar process from service entity. Multiple labels split by ",". |
+
+## Agent Sensor Mode
+
+Agent Sensor mode scanner could scan process which have installed the 
skywalking agent and report them.
+
+### Process Status Hook File Protocol
+
+The agent must be implemented the process status hook file protocol, then the 
rover could be collected the information of the process.
+
+This protocol is mainly is a metadata file, which contains the metadata of the 
process. 
+It should be saved in: 
`{TMPDIR}/apache_skywalking/process/{pid}/metadata.properties`, and update 
modify time with the interval to keep alive, the content in the `properties` 
format as below:
+
+| Key | Type | Description |
+|-----|------|------------|
+|layer|string|this process layer.|
+|service_name|string|this process service name.|
+|instance_name|string|this process instance name.|
+|process_name|string|this process process name, it's same with the instance 
name.|
+|properties|json|the properties in instance, the process labels also in the 
properties value.|
+|labels|string|the process labels, multiple labels split by ",".|
+|language|string|current process language, which is `golang`.|
+
+## Regex Mode
+
+Regex mode scanner could define a regex to filter which process declare to 
monitor by command line. 
+Multiple regex can be defined to mach different types of processes.
+
+Note, the duplicate processes entities cannot be reported. If multiple 
entities are generated, only one process will be reported.
+If the multiple finders could match the same process, only the first finder 
could be selected and reported.
+
+### Entity Builder
+
+The metadata of the process could build by the Go Template to help dynamically 
build them, also, you could just configure it as the string value, and it still 
works.
+
+These fields are supported using template to build:
+1. Service Name
+2. Service Instance Name
+3. Process NAme
+
+#### Context
+
+The context provides multiple functions for helping you build the process 
metadata.
+
+##### Rover
+
+Rover context provides the context of the rover process instance and VM data.
+
+| Name | Argument |  Example  | Description |
+|------|--------- |-----------|-------------|
+| InstanceID | None | `{{.Rover.InstanceID}}` | Get the Instance ID of the 
rover. |
+| HostIPV4 | The Interface name | `{{.Rover.HostIPV4 "en0"}}` | Get the ipv4 
address from the appointed network interface name. |
+| HostIPV6 | The Interface name | `{{.Rover.HostIPV6 "en0"}}` | Get the ipv6 
address from the appointed network interface name. |
+| HostName | None | `{{.Rover.HostName}}` | Get the host name of current 
machine.|
+
+##### Finder
+
+Finder context provides the context of the current process finder.
+
+| Name | Argument |  Example  | Description |
+|------|--------- |-----------|-------------|
+| Layer | None | `{{.Finder.Layer}}` | The layer of the current process which 
defines in the configuration | 
+| RegexMatchGroup | The index of the regex pattern | 
`{{.Finder.RegexMatchGroup 1}}`| When using the regex to match the process 
command line, it could use the group concept in the regex. This function could 
help you get the group value from it. |
+
+##### Process
+
+Process context provides the context relate to which process is matched.
+
+| Name | Argument |  Example  | Description |
+|------|--------- |-----------|-------------|
+| ExeFilePath | None | `{{.Process.ExeFilePath}}` | The execute file path of 
process. |
+| ExeName | None | `{{.Process.ExeName}}` | The execute file name. |
+| CommandLine | None | `{{.Process.CommandLine}}` | The command line of 
process. |
+| Pid | None | `{{.Process.Pid}}` | The id of the process. |
+| WorkDir | None | `{{.Process.WorkDir}}` | The work directory path of the 
process. |
\ No newline at end of file
diff --git a/docs/en/setup/examples/cases/agent-sensor/readme.md 
b/docs/en/setup/examples/cases/agent-sensor/readme.md
new file mode 100644
index 0000000..63f0a4c
--- /dev/null
+++ b/docs/en/setup/examples/cases/agent-sensor/readme.md
@@ -0,0 +1,50 @@
+# Detect Process by Agent Sensor
+
+This documentation helps you to set up service which could let rover detected 
automatically.
+
+## Configure Service
+
+Configure your service to enable the Process Status Hook feature. Take 
[go2sky](https://github.com/SkyAPM/go2sky) as an example here, which version 
must `>= v1.5.0`.
+
+```go
+// update the oap address here
+r, err := reporter.NewGRPCReporter("oap-skywalking:11800", 
reporter.WithProcessStatusHook(true))
+if err != nil {
+    log.Fatalf("new reporter error %v \n", err)
+}
+defer r.Close()
+tracer, err := go2sky.NewTracer("example", go2sky.WithReporter(r))
+```
+
+The `reporter.WithProcessStatusHook(true)` declare to enable the Process 
Status Hook feature.
+
+## Starting Rover
+
+### Enable Linux Process Scanner
+
+After your service been startup, then configure the Linux process scanner with 
"AGENT_SENSOR" mode.
+
+### Full Configuration
+
+Please follow the comment to update the backend address to your SkyWalking OAP 
address.
+
+```shell
+core:
+  backend:
+    addr: localhost:11800 # please change the backend address to your 
SkyWalking OAP address
+    enable_TLS: false
+    client_pem_path: "client.pem"
+    client_key_path: "client.key"
+    insecure_skip_verify: false
+    ca_pem_path: "ca.pem"
+    check_period: 5
+    authentication: ""
+    
+process_discovery:
+  heartbeat_period: 20s
+  scanner:
+    period: 3s
+    mode: AGENT_SENSOR
+    agent:
+      processStatusRefreshPeriod: 1m
+```
\ No newline at end of file
diff --git a/docs/en/setup/examples/cases/profiling-process/readme.md 
b/docs/en/setup/examples/cases/profiling-process/readme.md
index edcd137..e48a9c8 100644
--- a/docs/en/setup/examples/cases/profiling-process/readme.md
+++ b/docs/en/setup/examples/cases/profiling-process/readme.md
@@ -11,9 +11,9 @@ So we could locate the stack symbol, It could be checked 
following these ways:
 
 ## Starting Rover
 
-### Enable Linux Process Detector
+### Enable Linux Process Scanner
 
-After your service been startup, then configure the Linux process detector to 
let Rover known how to find service.
+After your service been startup, then configure the Linux process scanner to 
let Rover known how to find service.
 Please make sure the Linux Process Detector have been active.
 
 Then configure the finder to locate/identity service. It contains these data 
configure:
@@ -41,7 +41,7 @@ For the demo, we update the entity data as:
 4. **process**: As the executable file name: `sqrt`.
 5. **labels***: As empty.
 
-You could be following [this 
configuration](../../../configuration/process_discovery/linux.md) to get more 
configuration information.
+You could be following [this 
configuration](../../../configuration/process_discovery/scanner.md) to get more 
configuration information.
 
 ### Enable Profiling
 
@@ -67,11 +67,11 @@ core:
     
 process_discovery:
   heartbeat_period: 20s
-  vm:
-    active: true
+  scanner:
     period: 3s
-    finders:
-      - match_cmd_regex: sqrt
+    mode: REGEX
+    regex:
+      - match_cmd: sqrt
         layer: OS_LINUX
         service_name: sqrt
         instance_name: {{.Rover.HostIPV4 "en0"}}
diff --git a/docs/en/setup/overview.md b/docs/en/setup/overview.md
index b2c7528..a7efcf4 100644
--- a/docs/en/setup/overview.md
+++ b/docs/en/setup/overview.md
@@ -26,6 +26,7 @@ You can quickly build your Rover according to the following 
examples:
 ### Use Cases
 
 1. [Profiling a Golang/C service on 
Linux](examples/cases/profiling-process/readme.md)
+1. [Detect Process by Agent Sensor](examples/cases/agent-sensor/readme.md)
 
 ## Configuration
 
diff --git a/docs/menu.yml b/docs/menu.yml
index 4fb0730..42c9eae 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -55,6 +55,8 @@ catalog:
               catalog:
                 - name: Profiling a Golang/C service on Linux
                   path: /en/setup/examples/cases/profiling-process/readme
+                - name: Detect Process by Agent Sensor
+                  path: /en/setup/examples/cases/agent-sensor/readme
     - name: Guides
       catalog:
         - name: Contribution
diff --git a/pkg/process/api/process.go b/pkg/process/api/process.go
index b0f1dd2..19bcaae 100644
--- a/pkg/process/api/process.go
+++ b/pkg/process/api/process.go
@@ -23,14 +23,14 @@ type ProcessDetectType int8
 
 const (
        _ ProcessDetectType = iota
-       VM
-       KUBERNETES
+       Scanner
+       Kubernetes
 )
 
 func (d ProcessDetectType) Name() string {
-       if d == VM {
-               return "VM"
-       } else if d == KUBERNETES {
+       if d == Scanner {
+               return "Scanner"
+       } else if d == Kubernetes {
                return "Kubernetes"
        }
        return "not matched"
diff --git a/pkg/process/config.go b/pkg/process/config.go
index 36194ca..b201ced 100644
--- a/pkg/process/config.go
+++ b/pkg/process/config.go
@@ -19,7 +19,7 @@ package process
 
 import (
        "github.com/apache/skywalking-rover/pkg/module"
-       "github.com/apache/skywalking-rover/pkg/process/finders/vm"
+       "github.com/apache/skywalking-rover/pkg/process/finders/scanner"
 )
 
 type Config struct {
@@ -28,8 +28,8 @@ type Config struct {
        // heartbeat the process list period
        HeartbeatPeriod string `mapstructure:"heartbeat_period"`
 
-       // VM process finder
-       VM *vm.Config
+       // Scanner process from VM
+       Scanner *scanner.Config `mapstructure:"scanner"`
 }
 
 func (c *Config) IsActive() bool {
diff --git a/pkg/process/finders/base/config.go 
b/pkg/process/finders/base/config.go
index cd37580..6ba8144 100644
--- a/pkg/process/finders/base/config.go
+++ b/pkg/process/finders/base/config.go
@@ -18,6 +18,4 @@
 package base
 
 type FinderBaseConfig interface {
-       // ActiveFinder to detect process
-       ActiveFinder() bool
 }
diff --git a/pkg/process/finders/base/finder.go 
b/pkg/process/finders/base/finder.go
index 29733f6..1e3a288 100644
--- a/pkg/process/finders/base/finder.go
+++ b/pkg/process/finders/base/finder.go
@@ -55,4 +55,6 @@ type ProcessManager interface {
        GetModuleManager() *module.Manager
        // SyncAllProcessInFinder is mean synchronized all processes data from 
current ProcessFinder
        SyncAllProcessInFinder(processes []DetectedProcess)
+       // QueryProcess means get the process if already sync
+       QueryProcess(pid int32) DetectedProcess
 }
diff --git a/pkg/process/finders/manager.go b/pkg/process/finders/manager.go
index 1787cf5..e6d8977 100644
--- a/pkg/process/finders/manager.go
+++ b/pkg/process/finders/manager.go
@@ -53,7 +53,7 @@ func NewProcessManager(ctx context.Context, moduleManager 
*module.Manager,
        confinedFinders := make(map[base.FinderBaseConfig]base.ProcessFinder)
        fsList := make([]base.ProcessFinder, 0)
        for _, conf := range configs {
-               if conf == nil || !conf.ActiveFinder() {
+               if conf == nil {
                        continue
                }
                finder := getFinder(conf)
@@ -118,6 +118,10 @@ func (p *ProcessManagerWithFinder) 
SyncAllProcessInFinder(processes []base.Detec
        p.storage.SyncAllProcessInFinder(p.finderType, processes)
 }
 
+func (p *ProcessManagerWithFinder) QueryProcess(pid int32) 
base.DetectedProcess {
+       return p.storage.QueryProcess(pid)
+}
+
 func (m *ProcessManager) FindProcessByID(processID string) 
api.ProcessInterface {
        return m.storage.FindProcessByID(processID)
 }
diff --git a/pkg/process/finders/register.go b/pkg/process/finders/register.go
index 4f63bb8..babf52f 100644
--- a/pkg/process/finders/register.go
+++ b/pkg/process/finders/register.go
@@ -21,13 +21,13 @@ import (
        "reflect"
 
        "github.com/apache/skywalking-rover/pkg/process/finders/base"
-       "github.com/apache/skywalking-rover/pkg/process/finders/vm"
+       "github.com/apache/skywalking-rover/pkg/process/finders/scanner"
 )
 
 var finders = make(map[reflect.Type]base.ProcessFinder)
 
 func init() {
-       registerFinder(reflect.TypeOf(&vm.Config{}), &vm.ProcessFinder{})
+       registerFinder(reflect.TypeOf(&scanner.Config{}), 
&scanner.ProcessFinder{})
 }
 
 func registerFinder(t reflect.Type, finder base.ProcessFinder) {
diff --git a/pkg/process/finders/vm/config.go 
b/pkg/process/finders/scanner/config.go
similarity index 75%
rename from pkg/process/finders/vm/config.go
rename to pkg/process/finders/scanner/config.go
index ba36eec..01a2c2d 100644
--- a/pkg/process/finders/vm/config.go
+++ b/pkg/process/finders/scanner/config.go
@@ -15,33 +15,40 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package vm
+package scanner
 
 import (
        "regexp"
+       "time"
 
        "github.com/apache/skywalking-rover/pkg/process/finders/base"
 )
 
+type Mode string
+
+var (
+       Agent Mode = "AGENT_SENSOR"
+       Regex Mode = "REGEX"
+)
+
 type Config struct {
        base.FinderBaseConfig
 
-       Active bool `mapstructure:"active"`
-
-       // Check Period
+       // Scan Period
        Period string `mapstructure:"period"`
 
-       // Process finder list
-       Finders []*ProcessFinderConfig `mapstructure:"finders"`
-}
+       ScanMode Mode `mapstructure:"mode"`
 
-func (c *Config) ActiveFinder() bool {
-       return c.Active
+       // Agent process finder
+       Agent *AgentFinder `mapstructure:"agent"`
+
+       // Regex process finders
+       RegexFinders []*RegexFinder `mapstructure:"regex"`
 }
 
-type ProcessFinderConfig struct {
+type RegexFinder struct {
        // Use command line to match the processes
-       MatchCommandRegex string `mapstructure:"match_cmd_regex"`
+       MatchCommandRegex string `mapstructure:"match_cmd"`
 
        // entity
        Layer        string `mapstructure:"layer"`         // process layer
@@ -57,3 +64,9 @@ type ProcessFinderConfig struct {
        processNameBuilder  *base.TemplateBuilder
        ParsedLabels        []string
 }
+
+type AgentFinder struct {
+       ProcessStatusRefreshPeriod string 
`mapstructure:"process_status_refresh_period"` // match recent keep alive time
+
+       ProcessStatusRefreshPeriodDuration time.Duration
+}
diff --git a/pkg/process/finders/vm/finder.go 
b/pkg/process/finders/scanner/finder.go
similarity index 56%
rename from pkg/process/finders/vm/finder.go
rename to pkg/process/finders/scanner/finder.go
index 2f0abbb..cdc01ba 100644
--- a/pkg/process/finders/vm/finder.go
+++ b/pkg/process/finders/scanner/finder.go
@@ -15,16 +15,22 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package vm
+package scanner
 
 import (
+       "bufio"
+       "bytes"
        "context"
        "fmt"
        "os"
+       "path"
        "regexp"
+       "strconv"
        "strings"
        "time"
 
+       "github.com/spf13/viper"
+
        v3 "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/process/v3"
 
        "github.com/shirou/gopsutil/process"
@@ -36,7 +42,7 @@ import (
        "github.com/apache/skywalking-rover/pkg/tools/host"
 )
 
-var log = logger.GetLogger("process", "finder", "vm")
+var log = logger.GetLogger("process", "finder", "scanner")
 
 type ProcessFinder struct {
        conf *Config
@@ -75,7 +81,7 @@ func (p *ProcessFinder) Stop() error {
 }
 
 func (p *ProcessFinder) DetectType() api.ProcessDetectType {
-       return api.VM
+       return api.Scanner
 }
 
 func (p *ProcessFinder) ValidateProcessIsSame(p1, p2 base.DetectedProcess) 
bool {
@@ -114,28 +120,39 @@ func (p *ProcessFinder) ParseProcessID(ps 
base.DetectedProcess, downstream *v3.E
 
 func (p *ProcessFinder) startWatch() {
        // find one time
-       if err := p.findAndReportProcesses(); err != nil {
-               log.Warnf("list all process failure, %v", err)
-       }
+       p.findAndReportProcesses()
        // schedule
        ticker := time.NewTicker(p.period)
        for {
                select {
                case <-ticker.C:
-                       if err := p.findAndReportProcesses(); err != nil {
-                               log.Warnf("list all process failure, %v", err)
-                       }
+                       p.findAndReportProcesses()
                case <-p.ctx.Done():
                        return
                }
        }
 }
 
-func (p *ProcessFinder) findAndReportProcesses() error {
+func (p *ProcessFinder) findAndReportProcesses() {
+       var detectFunc func() ([]base.DetectedProcess, error)
+       if p.conf.ScanMode == Regex {
+               detectFunc = p.regexFindProcesses
+       } else if p.conf.ScanMode == Agent {
+               detectFunc = p.agentFindProcesses
+       }
+
+       if processes, err := detectFunc(); err != nil {
+               log.Warnf("list process failure, %v", err)
+       } else {
+               p.manager.SyncAllProcessInFinder(processes)
+       }
+}
+
+func (p *ProcessFinder) regexFindProcesses() ([]base.DetectedProcess, error) {
        // find all process
-       processes, err := p.findMatchedProcesses()
+       processes, err := p.regexFindMatchedProcesses()
        if err != nil {
-               return err
+               return nil, err
        }
 
        // validate the process could be profiling
@@ -146,33 +163,186 @@ func (p *ProcessFinder) findAndReportProcesses() error {
        for _, ps := range processes {
                psList = append(psList, ps)
        }
-       p.manager.SyncAllProcessInFinder(psList)
-       return nil
+       return psList, nil
 }
 
-func (p *ProcessFinder) validateTheProcessesCouldProfiling(processes 
[]*Process) []*Process {
-       result := make([]*Process, 0)
-       for _, ps := range processes {
-               exe := p.tryToFindFileExecutePath(ps.original)
-               if exe == "" {
-                       log.Warnf("could not read process exe file path, pid: 
%d", ps.pid)
+func (p *ProcessFinder) getProcessTempDir(pro *process.Process) (string, 
error) {
+       tmpDir := host.GetFileInHost(fmt.Sprintf("/proc/%d/root/tmp", pro.Pid))
+       environ, err := pro.Environ()
+       if err != nil {
+               log.Warnf("could not query the environments from the process, 
pid: %d, error: %v", pro.Pid, err)
+       }
+
+       prefix := "TMPDIR="
+       for _, env := range environ {
+               if strings.HasPrefix(env, prefix) {
+                       dir := 
host.GetFileInHost(fmt.Sprintf("/proc/%d/root/%s", pro.Pid, 
strings.TrimPrefix(env, prefix)))
+                       if pathExists(dir, nil) {
+                               return dir, nil
+                       }
+               }
+       }
+
+       if pathExists(tmpDir, nil) {
+               return tmpDir, nil
+       }
+       return "", fmt.Errorf("could not found tmp directory for pid: %d", 
pro.Pid)
+}
+
+func (p *ProcessFinder) agentFindProcesses() ([]base.DetectedProcess, error) {
+       // all system processes
+       processes, err := process.ProcessesWithContext(p.ctx)
+       if err != nil {
+               return nil, err
+       }
+       // find all matches processes
+       findedProcesses := make([]base.DetectedProcess, 0)
+       for _, pro := range processes {
+               // already contains the processes
+               pid := pro.Pid
+               if detectProcess := p.manager.QueryProcess(pid); detectProcess 
!= nil {
+                       findedProcesses = append(findedProcesses, detectProcess)
                        continue
                }
 
-               // check support profiling
-               if pf, err := tools.ExecutableFileProfilingStat(exe); err != 
nil {
-                       log.Warnf("the process could not be profiling, so 
ignored. pid: %d, reason: %v", ps.pid, err)
+               // if we cannot get temp directory, just ignore it
+               // May have some system process
+               tmpDir, err := p.getProcessTempDir(pro)
+               if err != nil {
+                       continue
+               }
+
+               metadataFilePath, metadataFile, err := 
p.tryingToGetAgentMetadataFile(pro, tmpDir)
+               if err != nil {
+                       log.Infof("found metadata file error, pid: %d, error: 
%v", pid, err)
+                       continue
+               }
+
+               // modify time + recent > now
+               // means the metadata file is acceptable
+               if 
!metadataFile.ModTime().Add(p.conf.Agent.ProcessStatusRefreshPeriodDuration).After(time.Now())
 {
                        continue
-               } else {
-                       ps.profiling = pf
                }
 
+               // build agent process
+               agentProcess, err := p.buildProcessFromAgentMetadata(pro, 
metadataFilePath)
+               if err != nil {
+                       log.Warnf("could not parsing metadata, pid: %d, error: 
%v", pid, err)
+                       continue
+               }
+
+               // could be profiling
+               if err := p.validateProcessCouldProfiling(agentProcess); err != 
nil {
+                       log.Warnf("found agent process, but it could not 
profiling, so ignore, pid: %d, error: %v", pid, err)
+                       continue
+               }
+
+               findedProcesses = append(findedProcesses, agentProcess)
+       }
+       return findedProcesses, nil
+}
+
+func (p *ProcessFinder) tryingToGetAgentMetadataFile(pro *process.Process, 
tmpDir string) (string, os.FileInfo, error) {
+       // get from the local machine
+       if f, info, err := p.tryingToGetAgentMetadataFileByPid(int64(pro.Pid), 
tmpDir); err == nil {
+               return f, info, nil
+       }
+
+       // get from the child ns(container)
+       processStatusFilePath := 
host.GetFileInHost(fmt.Sprintf("/proc/%d/status", pro.Pid))
+       processStatusFile, err := os.Open(processStatusFilePath)
+       if err != nil {
+               return "", nil, err
+       }
+       defer processStatusFile.Close()
+       scanner := bufio.NewScanner(processStatusFile)
+       for scanner.Scan() {
+               infos := strings.SplitN(scanner.Text(), "\t", 2)
+               if len(infos) < 2 {
+                       continue
+               }
+               if strings.TrimRight(infos[0], ":") == "NSpid" {
+                       pids := strings.Split(infos[1], "\t")
+                       if len(pids) <= 1 {
+                               break
+                       }
+                       nspidStr := pids[len(pids)-1]
+                       nspid, err := strconv.ParseInt(nspidStr, 10, 10)
+                       if err != nil {
+                               return "", nil, fmt.Errorf("could not parse the 
nspid: %s, %v", nspidStr, err)
+                       }
+                       if f, info, err := 
p.tryingToGetAgentMetadataFileByPid(nspid, tmpDir); err == nil {
+                               return f, info, nil
+                       }
+               }
+       }
+
+       return "", nil, fmt.Errorf("could not found")
+}
+
+func (p *ProcessFinder) tryingToGetAgentMetadataFileByPid(pid int64, tmpDir 
string) (string, os.FileInfo, error) {
+       metadataFile := path.Join(tmpDir, "apache_skywalking", "process", 
strconv.FormatInt(pid, 10), "metadata.properties")
+       f, err := os.Stat(metadataFile)
+       if err != nil {
+               return "", nil, err
+       }
+       return metadataFile, f, nil
+}
+
+func (p *ProcessFinder) buildProcessFromAgentMetadata(pro *process.Process, 
metaFilePath string) (*Process, error) {
+       metadata, err := os.ReadFile(metaFilePath)
+       if err != nil {
+               return nil, err
+       }
+
+       v := viper.New()
+       v.SetConfigType("properties")
+       if err1 := v.ReadConfig(bytes.NewReader(metadata)); err1 != nil {
+               return nil, err1
+       }
+
+       // parse agent data
+       agent := &AgentMetadata{}
+       if err1 := v.Unmarshal(agent); err1 != nil {
+               return nil, err1
+       }
+
+       cmdline, err := pro.Cmdline()
+       if err != nil {
+               return nil, err
+       }
+
+       return NewProcessByAgent(pro, cmdline, agent)
+}
+
+func (p *ProcessFinder) validateTheProcessesCouldProfiling(processes 
[]*Process) []*Process {
+       result := make([]*Process, 0)
+       for _, ps := range processes {
+               if err := p.validateProcessCouldProfiling(ps); err != nil {
+                       log.Warnf("could not read process exe file path, pid: 
%d", ps.pid)
+                       continue
+               }
                result = append(result, ps)
        }
        return result
 }
 
-func (p *ProcessFinder) findMatchedProcesses() ([]*Process, error) {
+func (p *ProcessFinder) validateProcessCouldProfiling(ps *Process) error {
+       exe := p.tryToFindFileExecutePath(ps.original)
+       if exe == "" {
+               return fmt.Errorf("could not read process exe file path, pid: 
%d", ps.pid)
+       }
+
+       // check support profiling
+       pf, err := tools.ExecutableFileProfilingStat(exe)
+       if err != nil {
+               return fmt.Errorf("the process could not be profiling, so 
ignored. pid: %d, reason: %v", ps.pid, err)
+       }
+       ps.profiling = pf
+       return nil
+}
+
+func (p *ProcessFinder) regexFindMatchedProcesses() ([]*Process, error) {
        // all system processes
        processes, err := process.ProcessesWithContext(p.ctx)
        if err != nil {
@@ -195,7 +365,7 @@ func (p *ProcessFinder) findMatchedProcesses() ([]*Process, 
error) {
                }
 
                // build the linux process and add to the list
-               ps := NewProcess(pro, cmdline, finderConfig)
+               ps := NewProcessByRegex(pro, cmdline, finderConfig)
                ps.entity.Layer = finderConfig.Layer
                ps.entity.ServiceName, err = p.buildEntity(err, ps, 
finderConfig.serviceNameBuilder)
                ps.entity.InstanceName, err = p.buildEntity(err, ps, 
finderConfig.instanceNameBuilder)
@@ -234,7 +404,7 @@ func (p *ProcessFinder) findMatchedProcesses() ([]*Process, 
error) {
                                WithField("process_name", 
reportProcess.entity.ProcessName).
                                WithField("labels", 
reportProcess.entity.Labels).
                                WithField("pid_list", pidList).
-                               Warnf("find multiple similar process in VM, " +
+                               Warnf("find multiple similar process in 
Scanner, " +
                                        "only report the first of these 
processes. " +
                                        "please update the name of process to 
identity them more clear.")
                }
@@ -250,7 +420,7 @@ func (p *ProcessFinder) buildEntity(err error, ps *Process, 
entity *base.Templat
        return renderTemplate(entity, ps, p)
 }
 
-func (p *ProcessFinder) findMatchesFinder(ps *process.Process) 
(*ProcessFinderConfig, string, error) {
+func (p *ProcessFinder) findMatchesFinder(ps *process.Process) (*RegexFinder, 
string, error) {
        // verify the process exists, if not exists just return
        if exists, err := process.PidExists(ps.Pid); err != nil {
                return nil, "", err
@@ -262,8 +432,8 @@ func (p *ProcessFinder) findMatchesFinder(ps 
*process.Process) (*ProcessFinderCo
        if err != nil {
                return nil, "", fmt.Errorf("query command line failure: %v", 
err)
        }
-       var matched *ProcessFinderConfig
-       for _, finder := range p.conf.Finders {
+       var matched *RegexFinder
+       for _, finder := range p.conf.RegexFinders {
                if finder.commandlineRegex.MatchString(cmdline) {
                        if matched == nil {
                                matched = finder
@@ -278,12 +448,20 @@ func (p *ProcessFinder) findMatchesFinder(ps 
*process.Process) (*ProcessFinderCo
 }
 
 func validateConfig(conf *Config) error {
-       if len(conf.Finders) == 0 {
-               return fmt.Errorf("must have one VM process finder")
+       if conf.ScanMode == Agent {
+               var err error
+               conf.Agent.ProcessStatusRefreshPeriodDuration, err = 
durationMustNotNull(err, "process_status_refresh_period",
+                       conf.Agent.ProcessStatusRefreshPeriod)
+               return err
+       } else if conf.ScanMode != Regex {
+               return fmt.Errorf("could not found mode: %s", conf.ScanMode)
+       }
+       if len(conf.RegexFinders) == 0 {
+               return fmt.Errorf("must have one Scanner process finder")
        }
 
        // validate config
-       for _, f := range conf.Finders {
+       for _, f := range conf.RegexFinders {
                var err error
                err = stringMustNotNull(err, "layer", f.Layer)
                f.commandlineRegex, err = regexMustNotNull(err, 
"match_cmd_regex", f.MatchCommandRegex)
@@ -316,7 +494,7 @@ func stringMustNotNull(err error, confKey, confValue 
string) error {
                return err
        }
        if confValue == "" {
-               return fmt.Errorf("the %s of VM process must be set", confKey)
+               return fmt.Errorf("the %s of Scanner process must be set", 
confKey)
        }
        return nil
 }
@@ -335,6 +513,13 @@ func regexMustNotNull(err error, confKey, confValue 
string) (*regexp.Regexp, err
        return regexp.Compile(confValue)
 }
 
+func durationMustNotNull(err error, confKey, confValue string) (time.Duration, 
error) {
+       if err1 := stringMustNotNull(err, confKey, confValue); err1 != nil {
+               return 0, err1
+       }
+       return time.ParseDuration(confValue)
+}
+
 func (p *ProcessFinder) tryToFindFileExecutePath(ps *process.Process) string {
        exe, err := ps.Exe()
        if pathExists(exe, err) {
@@ -360,5 +545,15 @@ func pathExists(exe string, err error) bool {
                return false
        }
        _, e := os.Stat(exe)
-       return e == nil
+       return !os.IsNotExist(e)
+}
+
+type AgentMetadata struct {
+       Layer        string `mapstructure:"layer"`
+       ServiceName  string `mapstructure:"service_name"`
+       InstanceName string `mapstructure:"instance_name"`
+       ProcessName  string `mapstructure:"process_name"`
+       Properties   string `mapstructure:"properties"`
+       Labels       string `mapstructure:"labels"`
+       Language     string `mapstructure:"language"`
 }
diff --git a/pkg/process/finders/vm/process.go 
b/pkg/process/finders/scanner/process.go
similarity index 60%
rename from pkg/process/finders/vm/process.go
rename to pkg/process/finders/scanner/process.go
index e5d373f..d90b655 100644
--- a/pkg/process/finders/vm/process.go
+++ b/pkg/process/finders/scanner/process.go
@@ -15,10 +15,11 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package vm
+package scanner
 
 import (
        "fmt"
+       "strings"
 
        "github.com/shirou/gopsutil/process"
 
@@ -29,7 +30,7 @@ import (
 type Process struct {
        // original reference
        original     *process.Process
-       finderConfig *ProcessFinderConfig
+       finderConfig *RegexFinder
 
        // process data
        pid       int32
@@ -40,10 +41,42 @@ type Process struct {
        entity *api.ProcessEntity
 }
 
-func NewProcess(p *process.Process, cmdline string, config 
*ProcessFinderConfig) *Process {
+func NewProcessByRegex(p *process.Process, cmdline string, config 
*RegexFinder) *Process {
        return &Process{original: p, pid: p.Pid, cmd: cmdline, finderConfig: 
config, entity: &api.ProcessEntity{}}
 }
 
+func NewProcessByAgent(p *process.Process, cmdline string, agent 
*AgentMetadata) (*Process, error) {
+       // basic data check
+       var err error
+       err = requiredNotNull(err, "layer", agent.Layer)
+       err = requiredNotNull(err, "service name", agent.ServiceName)
+       err = requiredNotNull(err, "instance name", agent.InstanceName)
+       err = requiredNotNull(err, "process name", agent.ProcessName)
+       if err != nil {
+               return nil, err
+       }
+
+       // labels getter
+       labels := make([]string, 0)
+       if agent.Labels != "" {
+               labels = strings.Split(agent.Labels, ",")
+       }
+
+       // build result
+       return &Process{
+               original: p,
+               pid:      p.Pid,
+               cmd:      cmdline,
+               entity: &api.ProcessEntity{
+                       Layer:        agent.Layer,
+                       ServiceName:  agent.ServiceName,
+                       InstanceName: agent.InstanceName,
+                       ProcessName:  agent.ProcessName,
+                       Labels:       labels,
+               },
+       }, nil
+}
+
 func (p *Process) Pid() int32 {
        return p.pid
 }
@@ -53,7 +86,7 @@ func (p *Process) Entity() *api.ProcessEntity {
 }
 
 func (p *Process) DetectType() api.ProcessDetectType {
-       return api.VM
+       return api.Scanner
 }
 
 func (p *Process) OriginalProcess() *process.Process {
@@ -69,3 +102,13 @@ func (p *Process) BuildIdentity() string {
        return fmt.Sprintf("%s_%s_%s_%s", p.entity.Layer, p.entity.ServiceName,
                p.entity.InstanceName, p.entity.ProcessName)
 }
+
+func requiredNotNull(err error, key, value string) error {
+       if err != nil {
+               return err
+       }
+       if value == "" {
+               return fmt.Errorf("the %s could not be null", key)
+       }
+       return nil
+}
diff --git a/pkg/process/finders/vm/template.go 
b/pkg/process/finders/scanner/template.go
similarity index 99%
rename from pkg/process/finders/vm/template.go
rename to pkg/process/finders/scanner/template.go
index 7268421..04fcdc3 100644
--- a/pkg/process/finders/vm/template.go
+++ b/pkg/process/finders/scanner/template.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package vm
+package scanner
 
 import (
        "fmt"
diff --git a/pkg/process/finders/storage.go b/pkg/process/finders/storage.go
index f5685d8..70f742a 100644
--- a/pkg/process/finders/storage.go
+++ b/pkg/process/finders/storage.go
@@ -182,6 +182,14 @@ func (s *ProcessStorage) 
processesReport(waitReportProcesses []*ProcessContext)
        return nil
 }
 
+func (s *ProcessStorage) QueryProcess(pid int32) base.DetectedProcess {
+       processContext := s.processes[pid]
+       if processContext != nil {
+               return processContext.detectProcess
+       }
+       return nil
+}
+
 func (s *ProcessStorage) SyncAllProcessInFinder(finder api.ProcessDetectType, 
processes []base.DetectedProcess) {
        s.mutex.Lock()
        defer s.mutex.Unlock()
@@ -208,7 +216,7 @@ func (s *ProcessStorage) SyncAllProcessInFinder(finder 
api.ProcessDetectType, pr
                }
 
                // they are the not same detect type
-               // TODO we just implement the VM mode process for now, so 
continue
+               // TODO we just implement the Scanner mode process for now, so 
continue
                if needToSyncProcess.DetectType() != 
managedProcess.DetectType() {
                        continue
                }
diff --git a/pkg/process/module.go b/pkg/process/module.go
index d57c3a3..74a9c41 100644
--- a/pkg/process/module.go
+++ b/pkg/process/module.go
@@ -56,7 +56,7 @@ func (m *Module) Start(ctx context.Context, mgr 
*module.Manager) error {
        if err != nil {
                return err
        }
-       processManager, err := finders.NewProcessManager(ctx, mgr, period, 
m.config.VM)
+       processManager, err := finders.NewProcessManager(ctx, mgr, period, 
m.config.Scanner)
        if err != nil {
                return err
        }
diff --git a/test/e2e/base/base-compose.yml b/test/e2e/base/base-compose.yml
index fa83014..7561a52 100644
--- a/test/e2e/base/base-compose.yml
+++ b/test/e2e/base/base-compose.yml
@@ -40,13 +40,14 @@ services:
       ROVER_HOST_MAPPING: /host
       ROVER_BACKEND_ADDR: oap:11800
       ROVER_PROCESS_DISCOVERY_HEARTBEAT_PERIOD: 2s
-      ROVER_PROCESS_DISCOVERY_VM_ACTIVE: "true"
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_MATCH_CMD_REGEX: sqrt
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_LAYER: OS_LINUX
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_SERVICE_NAME: sqrt
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_INSTANCE_NAME: test-instance
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_NAME: "{{.Process.ExeName}}"
-      ROVER_PROCESS_DISCOVERY_VM_FINDER_PROCESS_LABELS: e2e-label1,e2e-label2
+      ROVER_PROCESS_DISCOVERY_SCAN_PERIOD: 3s
+      ROVER_PROCESS_DISCOVERY_SCAN_MODE: "REGEX"
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_MATCH_CMD: sqrt
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LAYER: OS_LINUX
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_SERVICE_NAME: sqrt
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_INSTANCE_NAME: test-instance
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_PROCESS_NAME: 
"{{.Process.ExeName}}"
+      ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LABELS: e2e-label1,e2e-label2
       ROVER_PROFILING_ACTIVE: "true"
       ROVER_PROFILING_CHECK_INTERVAL: 2s
       ROVER_PROFILING_FLUSH_INTERVAL: 5s
diff --git a/test/e2e/base/env b/test/e2e/base/env
index b2d2380..1f008e8 100644
--- a/test/e2e/base/env
+++ b/test/e2e/base/env
@@ -14,3 +14,5 @@
 # limitations under the License.
 
 SW_CTL_COMMIT=5a62c2e029e17234e6bbad18ced0ce31d0f67ce9
+
+SW_AGENT_GO_COMMIT=216f122d942cb683f48578d3014cc5ea83637582
\ No newline at end of file
diff --git a/test/e2e/base/env 
b/test/e2e/cases/agent_sensor/golang/Dockerfile.go2sky
similarity index 62%
copy from test/e2e/base/env
copy to test/e2e/cases/agent_sensor/golang/Dockerfile.go2sky
index b2d2380..24e30ab 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/agent_sensor/golang/Dockerfile.go2sky
@@ -13,4 +13,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=5a62c2e029e17234e6bbad18ced0ce31d0f67ce9
+FROM golang:1.13 AS builder
+
+ARG SW_AGENT_GO_COMMIT
+ARG GO2SKY_CODE=${SW_AGENT_GO_COMMIT}.tar.gz
+ARG GO2SKY_CODE_URL=https://github.com/SkyAPM/go2sky/archive/${GO2SKY_CODE}
+
+ENV CGO_ENABLED=0
+ENV GO111MODULE=on
+
+WORKDIR /go2sky
+
+ADD ${GO2SKY_CODE_URL} .
+RUN tar -xf ${GO2SKY_CODE} --strip 1
+RUN rm ${GO2SKY_CODE}
+
+WORKDIR /go2sky/test/e2e/example-server
+RUN go build -o main
+
+FROM alpine:3.10
+
+COPY --from=builder /go2sky/test/e2e/example-server/main .
+ENTRYPOINT ["/main"]
diff --git a/test/e2e/cases/agent_sensor/golang/docker-compose.yml 
b/test/e2e/cases/agent_sensor/golang/docker-compose.yml
new file mode 100644
index 0000000..55e83c5
--- /dev/null
+++ b/test/e2e/cases/agent_sensor/golang/docker-compose.yml
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: '2.1'
+
+services:
+  oap:
+    extends:
+      file: ../../../base/base-compose.yml
+      service: oap
+    ports:
+      - 12800:12800
+
+  rover:
+    extends:
+      file: ../../../base/base-compose.yml
+      service: rover
+    environment:
+      ROVER_PROCESS_DISCOVERY_SCAN_MODE: AGENT_SENSOR
+    depends_on:
+      oap:
+        condition: service_healthy
+
+  go2sky:
+    build:
+      context: .
+      dockerfile: Dockerfile.go2sky
+      args:
+        - SW_AGENT_GO_COMMIT=${SW_AGENT_GO_COMMIT}
+    networks:
+      - e2e
+    depends_on:
+      oap:
+        condition: service_healthy
+    command: [ '--grpc', '--oap-server', 'oap:11800']
+    environment:
+      SW_AGENT_PROCESS_STATUS_HOOK_ENABLE: "true"
+      SW_AGENT_PROCESS_LABELS: e2e-label
+      SW_AGENT_NAME: go2sky
+      SW_AGENT_INSTANCE_NAME: go2sky-instance
+    healthcheck:
+      test: [ "CMD", "sh", "-c", "nc -z 127.0.0.1 8080" ]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+networks:
+  e2e:
\ No newline at end of file
diff --git a/test/e2e/cases/agent_sensor/golang/e2e.yaml 
b/test/e2e/cases/agent_sensor/golang/e2e.yaml
new file mode 100644
index 0000000..6806cfa
--- /dev/null
+++ b/test/e2e/cases/agent_sensor/golang/e2e.yaml
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+setup:
+  env: compose
+  file: docker-compose.yml
+  timeout: 20m
+  init-system-environment: ../../../base/env
+  steps:
+    - name: set PATH
+      command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
+    - name: install yq
+      command: bash test/e2e/base/scripts/prepare/setup-e2e-shell/install.sh yq
+    - name: install swctl
+      command: bash test/e2e/base/scripts/prepare/setup-e2e-shell/install.sh 
swctl
+
+verify:
+  # verify with retry strategy
+  retry:
+    # max retry count
+    count: 20
+    # the interval between two retries, in millisecond.
+    interval: 10s
+  cases:
+    - query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql 
--display yaml service ls
+      expected: expected/service.yml
+    - query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql 
--display yaml instance ls --service-name go2sky
+      expected: expected/instance.yml
+    - query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql 
--display yaml process ls --service-name go2sky --instance-name go2sky-instance
+      expected: expected/process.yml
\ No newline at end of file
diff --git a/test/e2e/base/env 
b/test/e2e/cases/agent_sensor/golang/expected/instance.yml
similarity index 62%
copy from test/e2e/base/env
copy to test/e2e/cases/agent_sensor/golang/expected/instance.yml
index b2d2380..9c86379 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/agent_sensor/golang/expected/instance.yml
@@ -13,4 +13,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=5a62c2e029e17234e6bbad18ced0ce31d0f67ce9
+{{- contains . }}
+- id: {{ b64enc "go2sky" }}.1_{{ b64enc "go2sky-instance" }}
+  name: go2sky-instance
+  attributes:
+  {{- contains .attributes }}
+  - name: Process No.
+    value: "1"
+  - name: hostname
+    value: {{ notEmpty .value }}
+  - name: OS Name
+    value: linux
+  - name: processLabels
+    value: e2e-label
+  - name: ipv4s
+    value: {{ notEmpty .value }}
+  {{- end }}
+  language: GO
+  instanceuuid: {{ notEmpty .instanceuuid }}
+  layer: GENERAL
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e/base/env 
b/test/e2e/cases/agent_sensor/golang/expected/process.yml
similarity index 57%
copy from test/e2e/base/env
copy to test/e2e/cases/agent_sensor/golang/expected/process.yml
index b2d2380..ca17857 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/agent_sensor/golang/expected/process.yml
@@ -13,4 +13,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=5a62c2e029e17234e6bbad18ced0ce31d0f67ce9
+{{- contains . }}
+- id: {{ notEmpty .id }}
+  name: go2sky-instance
+  serviceid: {{ b64enc "go2sky" }}.1
+  servicename: go2sky
+  instanceid: {{ b64enc "go2sky" }}.1_{{ b64enc "go2sky-instance" }}
+  instancename: go2sky-instance
+  layer: GENERAL
+  agentid: {{ notEmpty .agentid }}
+  detecttype: VM
+  attributes:
+    {{- contains .attributes }}
+    - name: host_ip
+      value: {{ notEmpty .value }}
+    - name: pid
+      value: {{ notEmpty .value }}
+    - name: command_line
+      value: /main --grpc --oap-server oap:11800
+    {{- end }}
+  labels:
+    - e2e-label
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e/base/env 
b/test/e2e/cases/agent_sensor/golang/expected/service.yml
similarity index 84%
copy from test/e2e/base/env
copy to test/e2e/cases/agent_sensor/golang/expected/service.yml
index b2d2380..5b244c0 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/agent_sensor/golang/expected/service.yml
@@ -13,4 +13,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=5a62c2e029e17234e6bbad18ced0ce31d0f67ce9
+{{- contains . }}
+- id: {{ b64enc "go2sky" }}.1
+  name: go2sky
+  group: ""
+  shortname: go2sky
+  layers:
+    - GENERAL
+  normal: true
+{{- end }}
\ No newline at end of file

Reply via email to