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

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git


The following commit(s) were added to refs/heads/master by this push:
     new 0d03a08  把你这次修改的代码stage一下,而且,这个修改我要git commit了,给我一个符合semantic 
release的git commit message(英文)(不要文本本身,不要git命令),要短一点,半句话就行
0d03a08 is described below

commit 0d03a0821da33211151e7617575a376c2f9d2433
Author: Yang Luo <[email protected]>
AuthorDate: Mon Aug 24 17:39:04 2026 +0800

    把你这次修改的代码stage一下,而且,这个修改我要git commit了,给我一个符合semantic release的git commit 
message(英文)(不要文本本身,不要git命令),要短一点,半句话就行
---
 agentpatch/auto.go   | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 agentpatch/patch.go  | 11 +++++--
 conf/app.conf        |  5 +--
 conf/conf.go         | 10 +++---
 controllers/agent.go |  4 +++
 main.go              | 10 ++++++
 6 files changed, 117 insertions(+), 9 deletions(-)

diff --git a/agentpatch/auto.go b/agentpatch/auto.go
new file mode 100644
index 0000000..244f809
--- /dev/null
+++ b/agentpatch/auto.go
@@ -0,0 +1,86 @@
+// Copyright 2026 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agentpatch
+
+import (
+       "errors"
+       "fmt"
+       "os"
+       "path/filepath"
+       "time"
+
+       "github.com/apache/casbin-gateway/agent"
+)
+
+// Monitoring is on by default: an installation Gateway finds is patched 
without
+// waiting for a click. Turning one off by hand leaves an opt-out marker beside
+// its manifest, so the next scan leaves that installation alone.
+
+func optOutPath(target Target) string {
+       return filepath.Join(stateDir(), targetKey(target)+".off")
+}
+
+func isOptedOut(target Target) bool {
+       _, err := os.Stat(optOutPath(target))
+       return err == nil
+}
+
+func setOptOut(target Target, off bool) {
+       if !off {
+               _ = os.Remove(optOutPath(target))
+               return
+       }
+       if err := os.MkdirAll(stateDir(), 0o700); err != nil {
+               return
+       }
+       _ = os.WriteFile(optOutPath(target), 
[]byte(time.Now().Format(time.RFC3339)), 0o600)
+}
+
+// EnsurePatched turns monitoring on for one installation, unless it cannot be
+// monitored, already is, or was turned off by hand.
+func EnsurePatched(target Target) error {
+       patcher, ok := patchers[target.AgentId]
+       if !ok || !patcher.Supported() || isOptedOut(target) {
+               return nil
+       }
+
+       status, err := patcher.Status(target)
+       if err != nil {
+               return err
+       }
+       if status.Patched {
+               return nil
+       }
+       return patcher.Patch(target)
+}
+
+// EnableAll turns monitoring on for every agent installed on this host. The
+// failures are joined so one installation that cannot be patched neither hides
+// the others nor stops them.
+func EnableAll() error {
+       installations, err := agent.Scan(false)
+       if err != nil {
+               return err
+       }
+
+       failures := []error{}
+       for _, installation := range installations {
+               target := Target{AgentId: installation.AgentId, Path: 
installation.Path, Owner: installation.Owner}
+               if err := EnsurePatched(target); err != nil {
+                       failures = append(failures, fmt.Errorf("%s: %w", 
installation.AgentId, err))
+               }
+       }
+       return errors.Join(failures...)
+}
diff --git a/agentpatch/patch.go b/agentpatch/patch.go
index bd9f214..98fdb90 100644
--- a/agentpatch/patch.go
+++ b/agentpatch/patch.go
@@ -90,15 +90,22 @@ func Patch(target Target) error {
        if err != nil {
                return err
        }
-       return patcher.Patch(target)
+       if err := patcher.Patch(target); err != nil {
+               return err
+       }
+       setOptOut(target, false)
+       return nil
 }
 
-// Unpatch disables monitoring and restores files changed by Patch.
+// Unpatch disables monitoring and restores files changed by Patch. Monitoring
+// being on by default, the choice is remembered so no later scan turns it back
+// on.
 func Unpatch(target Target) error {
        patcher, err := patcherFor(target)
        if err != nil {
                return err
        }
+       setOptOut(target, true)
        return patcher.Unpatch(target)
 }
 
diff --git a/conf/app.conf b/conf/app.conf
index 7ceba26..9c580ee 100644
--- a/conf/app.conf
+++ b/conf/app.conf
@@ -104,8 +104,9 @@ agentMonitorPollSeconds = 5
 
 ; LLM request records. "off" keeps nothing, "metadata" records who called which
 ; model with which outcome, and "full" also stores the sanitized request body.
-; Anything beyond "off" is opt-in because prompts can carry sensitive data.
-llmRecordMode = "off"
+; The default is "full": the records are what the dashboards are made of, and
+; they stay on this machine. Set it to "metadata" or "off" to keep less.
+llmRecordMode = "full"
 llmRecordQueueCapacity = 1000
 llmRecordRetentionDays = 30
 llmRecordMaxRecords = 10000
diff --git a/conf/conf.go b/conf/conf.go
index d68639a..c7defb4 100644
--- a/conf/conf.go
+++ b/conf/conf.go
@@ -300,16 +300,16 @@ const (
 )
 
 // GetLlmRecordMode reports whether LLM requests are recorded, and whether the
-// request body is kept along with the metadata. Prompts are sensitive, so the
-// default is to keep nothing.
+// request body is kept along with the metadata. Recording is on by default, so
+// anything but an explicit "off" or "metadata" keeps the whole request.
 func GetLlmRecordMode() string {
        switch strings.ToLower(strings.Trim(GetConfigString("llmRecordMode"), 
`"' `)) {
+       case LlmRecordOff:
+               return LlmRecordOff
        case LlmRecordMetadata:
                return LlmRecordMetadata
-       case LlmRecordFull:
-               return LlmRecordFull
        default:
-               return LlmRecordOff
+               return LlmRecordFull
        }
 }
 
diff --git a/controllers/agent.go b/controllers/agent.go
index 62bc600..fd8fc6a 100644
--- a/controllers/agent.go
+++ b/controllers/agent.go
@@ -68,6 +68,10 @@ func (c *ApiController) GetAgents() {
        result := make([]*discoveredAgent, 0, len(installations))
        for _, installation := range installations {
                target := targetOf(installation)
+               // Monitoring is on by default, so an installation that is not 
monitored
+               // yet is patched here instead of waiting for the switch to be 
flipped.
+               // A failure is left to the status below, which says what is 
wrong.
+               _ = agentpatch.EnsurePatched(target)
                item := &discoveredAgent{
                        Installation:   installation,
                        Status:         agentpatch.StatusOf(target),
diff --git a/main.go b/main.go
index 7a8d467..fe6c708 100644
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ import (
 
        "github.com/apache/casbin-gateway/agenthook"
        "github.com/apache/casbin-gateway/agentmonitor"
+       "github.com/apache/casbin-gateway/agentpatch"
        "github.com/apache/casbin-gateway/casdoor"
        "github.com/apache/casbin-gateway/conf"
        "github.com/apache/casbin-gateway/ip"
@@ -93,6 +94,15 @@ func main() {
        }
        defer agentmonitor.Stop()
 
+       // Monitoring is on by default, so the agents already on this host are
+       // patched without anyone opening the UI. The scan walks the disk, 
hence the
+       // goroutine.
+       go func() {
+               if err := agentpatch.EnableAll(); err != nil {
+                       beego.Error("agent monitoring could not be enabled:", 
err)
+               }
+       }()
+
        // An update ends this process without unwinding main, so what the 
deferred
        // calls above would have flushed has to be flushed there instead.
        version.BeforeRestart = func() {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to