Re: [PR] feat: mcp-log [dubbo-admin]
robocanic merged PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4825640723 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
robocanic commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4825636877 LGTM. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4698507368 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4698507365 @robocanic done -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407944375
##
pkg/mcp/register.go:
##
@@ -310,4 +311,35 @@ func RegisterTools(server *Server) {
},
Handler: tools.GetApplicationServices,
})
+
+ logSearchProperties := logtools.LogSearchProperties()
+ server.RegisterTool(&common.ToolDef{
+ Name:"search_logs",
+ Description: "查询 Dubbo 服务日志,支持按应用、服务、实例、TraceID 和关键字过滤",
+ InputSchema: common.InputSchema{
+ Type: "object",
+ Properties: logSearchProperties,
+ },
+ Handler: logtools.SearchLogs,
+ })
+
+ server.RegisterTool(&common.ToolDef{
+ Name:"analyze_error_logs",
+ Description: "分析错误日志并按错误模式聚合",
+ InputSchema: common.InputSchema{
+ Type: "object",
+ Properties: logSearchProperties,
+ },
+ Handler: logtools.AnalyzeErrorLogs,
+ })
+
+ server.RegisterTool(&common.ToolDef{
+ Name:"get_log_capabilities",
+ Description: "获取日志查询能力,返回 Loki 当前可用 labels 以及查询参数到 labels 的映射",
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
-
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407943709
##
pkg/config/observability/logs.go:
##
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package observability
+
+import (
+ "fmt"
+ "net/url"
+
+ "github.com/duke-git/lancet/v2/strutil"
+
+ "github.com/apache/dubbo-admin/pkg/common/bizerror"
+)
+
+type LogProviderType string
+
+const (
+ LogProviderLoki LogProviderType = "loki"
+)
+
+type LogsConfig struct {
+ DefaultProvider string `json:"defaultProvider"
yaml:"defaultProvider"`
+ Providers []LogProviderConfig `json:"providers" yaml:"providers"`
+}
+
+type LogProviderConfig struct {
+ Name string `json:"name" yaml:"name"`
+ Type LogProviderType `json:"type" yaml:"type"`
+ Endpoint string `json:"endpoint" yaml:"endpoint"`
+ Tenant string `json:"tenant,omitempty"
yaml:"tenant,omitempty"`
+}
+
+func (c *LogsConfig) Validate() error {
+ if c == nil || len(c.Providers) == 0 {
+ return nil
+ }
+ if strutil.IsBlank(c.DefaultProvider) {
+ return bizerror.New(bizerror.ConfigError, "default log provider
is required")
+ }
+
+ foundDefault := false
+ for _, provider := range c.Providers {
+ if strutil.IsBlank(provider.Name) {
+ return bizerror.New(bizerror.ConfigError, "log provider
name is required")
+ }
+ if provider.Name == c.DefaultProvider {
+ foundDefault = true
+ }
+ if provider.Type != LogProviderLoki {
+ return bizerror.New(bizerror.ConfigError,
fmt.Sprintf("unsupported log provider type: %s", provider.Type))
+ }
+ if strutil.IsBlank(provider.Endpoint) {
+ return bizerror.New(bizerror.ConfigError, "log provider
endpoint is required")
+ }
+ if _, err := url.Parse(provider.Endpoint); err != nil {
+ return bizerror.Wrap(err, bizerror.ConfigError,
fmt.Sprintf("invalid log provider endpoint: %s", provider.Endpoint))
+ }
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
-
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407940460
##
pkg/mcp/tools/log/loki.go:
##
@@ -0,0 +1,610 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/apache/dubbo-admin/pkg/common/bizerror"
+ observabilitycfg
"github.com/apache/dubbo-admin/pkg/config/observability"
+)
+
+const (
+ defaultQueryWindow = time.Hour
+ labelCacheTTL = 5 * time.Minute
+)
+
+var fallbackSelectorPriority = []string{
+ "namespace",
+ "job",
+ "app",
+ "appName",
+ "service_name",
+ "serviceName",
+ "service",
+ "pod",
+ "container",
+ "instance",
+ "instanceName",
+ "level",
+}
+
+var lokiLabelsCache = struct {
+ sync.Mutex
+ items map[string]cachedLokiLabels
+}{
+ items: map[string]cachedLokiLabels{},
+}
+
+type cachedLokiLabels struct {
+ labelsmap[string]struct{}
+ expiresAt time.Time
+}
+
+type lokiClient struct {
+ config observabilitycfg.LogProviderConfig
+ client *http.Client
+}
+
+type lokiQueryRangeResp struct {
+ Status string `json:"status"`
+ Data struct {
+ Result []lokiStream `json:"result"`
+ } `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiLabelsResp struct {
+ Status string `json:"status"`
+ Data []string `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiStream struct {
+ Stream map[string]string `json:"stream"`
+ Values [][]string`json:"values"`
+}
+
+func newLokiClient(cfg observabilitycfg.LogProviderConfig) *lokiClient {
+ return &lokiClient{
+ config: cfg,
+ client: &http.Client{Timeout: 30 * time.Second},
+ }
+}
+
+func (c *lokiClient) search(ctx context.Context, req *SearchLogsReq)
(*SearchLogsResp, error) {
+ if req.Limit <= 0 {
+ req.Limit = defaultLogLimit
+ }
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+
+ labelNames, _ := c.labelNames(ctx, start, end)
+ queries := buildLogQLQueriesWithLabels(req, labelNames)
+ merged := &SearchLogsResp{SourceEngine: "loki", Logs: make([]LogItem,
0, req.Limit)}
+ seen := map[string]struct{}{}
+ for _, query := range queries {
+ logs, err := c.queryRange(ctx, query, start, end, req.Limit)
+ if err != nil {
+ return nil, err
+ }
+ // remove duplicates
+ for _, item := range logs {
+ key := dedupeKey(item)
+ if _, ok := seen[key]; ok {
+ continue
+ }
+ seen[key] = struct{}{}
+ merged.Logs = append(merged.Logs, item)
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+
+ sort.SliceStable(merged.Logs, func(i, j int) bool {
+ return merged.Logs[i].Timestamp > merged.Logs[j].Timestamp
+ })
+ return merged, nil
+}
+
+func (c *lokiClient) capabilities(ctx context.Context, req
*LogCapabilitiesReq) (*LogCapabilitiesResp, error) {
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+ labelNames, err := c.labelNames(ctx, start, end)
+ if err != nil {
+ return nil, err
+ }
+
+ return &LogCapabilitiesResp{
+ AvailableLabels: supportedLabels(labelNames),
+ SupportedFilters: []string{
+ "mesh",
+ "appName
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407935291
##
pkg/mcp/tools/log/loki.go:
##
@@ -0,0 +1,610 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/apache/dubbo-admin/pkg/common/bizerror"
+ observabilitycfg
"github.com/apache/dubbo-admin/pkg/config/observability"
+)
+
+const (
+ defaultQueryWindow = time.Hour
+ labelCacheTTL = 5 * time.Minute
+)
+
+var fallbackSelectorPriority = []string{
+ "namespace",
+ "job",
+ "app",
+ "appName",
+ "service_name",
+ "serviceName",
+ "service",
+ "pod",
+ "container",
+ "instance",
+ "instanceName",
+ "level",
+}
+
+var lokiLabelsCache = struct {
+ sync.Mutex
+ items map[string]cachedLokiLabels
+}{
+ items: map[string]cachedLokiLabels{},
+}
+
+type cachedLokiLabels struct {
+ labelsmap[string]struct{}
+ expiresAt time.Time
+}
+
+type lokiClient struct {
+ config observabilitycfg.LogProviderConfig
+ client *http.Client
+}
+
+type lokiQueryRangeResp struct {
+ Status string `json:"status"`
+ Data struct {
+ Result []lokiStream `json:"result"`
+ } `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiLabelsResp struct {
+ Status string `json:"status"`
+ Data []string `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiStream struct {
+ Stream map[string]string `json:"stream"`
+ Values [][]string`json:"values"`
+}
+
+func newLokiClient(cfg observabilitycfg.LogProviderConfig) *lokiClient {
+ return &lokiClient{
+ config: cfg,
+ client: &http.Client{Timeout: 30 * time.Second},
+ }
+}
+
+func (c *lokiClient) search(ctx context.Context, req *SearchLogsReq)
(*SearchLogsResp, error) {
+ if req.Limit <= 0 {
+ req.Limit = defaultLogLimit
+ }
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+
+ labelNames, _ := c.labelNames(ctx, start, end)
+ queries := buildLogQLQueriesWithLabels(req, labelNames)
+ merged := &SearchLogsResp{SourceEngine: "loki", Logs: make([]LogItem,
0, req.Limit)}
+ seen := map[string]struct{}{}
+ for _, query := range queries {
+ logs, err := c.queryRange(ctx, query, start, end, req.Limit)
+ if err != nil {
+ return nil, err
+ }
+ // remove duplicates
+ for _, item := range logs {
+ key := dedupeKey(item)
+ if _, ok := seen[key]; ok {
+ continue
+ }
+ seen[key] = struct{}{}
+ merged.Logs = append(merged.Logs, item)
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+
+ sort.SliceStable(merged.Logs, func(i, j int) bool {
+ return merged.Logs[i].Timestamp > merged.Logs[j].Timestamp
+ })
+ return merged, nil
+}
+
+func (c *lokiClient) capabilities(ctx context.Context, req
*LogCapabilitiesReq) (*LogCapabilitiesResp, error) {
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+ labelNames, err := c.labelNames(ctx, start, end)
+ if err != nil {
+ return nil, err
+ }
+
+ return &LogCapabilitiesResp{
+ AvailableLabels: supportedLabels(labelNames),
+ SupportedFilters: []string{
+ "mesh",
+ "appName
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407923217
##
pkg/mcp/tools/log/loki.go:
##
@@ -0,0 +1,610 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/apache/dubbo-admin/pkg/common/bizerror"
+ observabilitycfg
"github.com/apache/dubbo-admin/pkg/config/observability"
+)
+
+const (
+ defaultQueryWindow = time.Hour
+ labelCacheTTL = 5 * time.Minute
+)
+
+var fallbackSelectorPriority = []string{
+ "namespace",
+ "job",
+ "app",
+ "appName",
+ "service_name",
+ "serviceName",
+ "service",
+ "pod",
+ "container",
+ "instance",
+ "instanceName",
+ "level",
+}
+
+var lokiLabelsCache = struct {
+ sync.Mutex
+ items map[string]cachedLokiLabels
+}{
+ items: map[string]cachedLokiLabels{},
+}
+
+type cachedLokiLabels struct {
+ labelsmap[string]struct{}
+ expiresAt time.Time
+}
+
+type lokiClient struct {
+ config observabilitycfg.LogProviderConfig
+ client *http.Client
+}
+
+type lokiQueryRangeResp struct {
+ Status string `json:"status"`
+ Data struct {
+ Result []lokiStream `json:"result"`
+ } `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiLabelsResp struct {
+ Status string `json:"status"`
+ Data []string `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiStream struct {
+ Stream map[string]string `json:"stream"`
+ Values [][]string`json:"values"`
+}
+
+func newLokiClient(cfg observabilitycfg.LogProviderConfig) *lokiClient {
+ return &lokiClient{
+ config: cfg,
+ client: &http.Client{Timeout: 30 * time.Second},
+ }
+}
+
+func (c *lokiClient) search(ctx context.Context, req *SearchLogsReq)
(*SearchLogsResp, error) {
+ if req.Limit <= 0 {
+ req.Limit = defaultLogLimit
+ }
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+
+ labelNames, _ := c.labelNames(ctx, start, end)
+ queries := buildLogQLQueriesWithLabels(req, labelNames)
+ merged := &SearchLogsResp{SourceEngine: "loki", Logs: make([]LogItem,
0, req.Limit)}
+ seen := map[string]struct{}{}
+ for _, query := range queries {
+ logs, err := c.queryRange(ctx, query, start, end, req.Limit)
+ if err != nil {
+ return nil, err
+ }
+ // remove duplicates
+ for _, item := range logs {
+ key := dedupeKey(item)
+ if _, ok := seen[key]; ok {
+ continue
+ }
+ seen[key] = struct{}{}
+ merged.Logs = append(merged.Logs, item)
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+ if len(merged.Logs) >= req.Limit {
+ break
+ }
+ }
+
+ sort.SliceStable(merged.Logs, func(i, j int) bool {
+ return merged.Logs[i].Timestamp > merged.Logs[j].Timestamp
+ })
+ return merged, nil
+}
+
+func (c *lokiClient) capabilities(ctx context.Context, req
*LogCapabilitiesReq) (*LogCapabilitiesResp, error) {
+ start, end, err := resolveTimeRange(req.StartTime, req.EndTime)
+ if err != nil {
+ return nil, err
+ }
+ labelNames, err := c.labelNames(ctx, start, end)
+ if err != nil {
+ return nil, err
+ }
+
+ return &LogCapabilitiesResp{
+ AvailableLabels: supportedLabels(labelNames),
+ SupportedFilters: []string{
+ "mesh",
+ "appName
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407906419
##
pkg/mcp/tools/log/analyzer.go:
##
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "fmt"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+var volatileTokenPattern = regexp.MustCompile(`(?i)\b[0-9a-f]{8,}\b|\b\d+\b`)
+
+func analyzeErrors(logs []LogItem, sourceEngine string) *AnalyzeErrorLogsResp {
+ patternsByName := map[string]*ErrorPattern{}
+ for _, item := range logs {
+ if !isErrorLog(item) {
+ continue
+ }
+ patternName := normalizeMessagePattern(item.Message)
+ pattern := patternsByName[patternName]
+ if pattern == nil {
+ pattern = &ErrorPattern{
+ Pattern: patternName,
+ Example: item.Message,
+ FirstSeen: item.Timestamp,
+ LastSeen: item.Timestamp,
+ }
+ patternsByName[patternName] = pattern
+ }
+ pattern.Count++
+ pattern.LastSeen = item.Timestamp
+ if len(pattern.Examples) < 3 {
+ pattern.Examples = append(pattern.Examples, item)
+ }
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
-
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Copilot commented on code in PR #1483:
URL: https://github.com/apache/dubbo-admin/pull/1483#discussion_r3407671797
##
pkg/mcp/tools/log/analyzer.go:
##
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "fmt"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+var volatileTokenPattern = regexp.MustCompile(`(?i)\b[0-9a-f]{8,}\b|\b\d+\b`)
+
+func analyzeErrors(logs []LogItem, sourceEngine string) *AnalyzeErrorLogsResp {
+ patternsByName := map[string]*ErrorPattern{}
+ for _, item := range logs {
+ if !isErrorLog(item) {
+ continue
+ }
+ patternName := normalizeMessagePattern(item.Message)
+ pattern := patternsByName[patternName]
+ if pattern == nil {
+ pattern = &ErrorPattern{
+ Pattern: patternName,
+ Example: item.Message,
+ FirstSeen: item.Timestamp,
+ LastSeen: item.Timestamp,
+ }
+ patternsByName[patternName] = pattern
+ }
+ pattern.Count++
+ pattern.LastSeen = item.Timestamp
+ if len(pattern.Examples) < 3 {
+ pattern.Examples = append(pattern.Examples, item)
+ }
Review Comment:
`FirstSeen`/`LastSeen` are updated in a way that depends on input order.
Since `SearchLogs` sorts logs descending, the current `pattern.LastSeen =
item.Timestamp` ends up setting `LastSeen` to the oldest entry and never
corrects `FirstSeen` when older entries are encountered. Update both fields
using min/max comparisons instead of unconditional assignment.
##
pkg/mcp/tools/log/loki.go:
##
@@ -0,0 +1,610 @@
+/*
+ * 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.
+ */
+
+package log
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/apache/dubbo-admin/pkg/common/bizerror"
+ observabilitycfg
"github.com/apache/dubbo-admin/pkg/config/observability"
+)
+
+const (
+ defaultQueryWindow = time.Hour
+ labelCacheTTL = 5 * time.Minute
+)
+
+var fallbackSelectorPriority = []string{
+ "namespace",
+ "job",
+ "app",
+ "appName",
+ "service_name",
+ "serviceName",
+ "service",
+ "pod",
+ "container",
+ "instance",
+ "instanceName",
+ "level",
+}
+
+var lokiLabelsCache = struct {
+ sync.Mutex
+ items map[string]cachedLokiLabels
+}{
+ items: map[string]cachedLokiLabels{},
+}
+
+type cachedLokiLabels struct {
+ labelsmap[string]struct{}
+ expiresAt time.Time
+}
+
+type lokiClient struct {
+ config observabilitycfg.LogProviderConfig
+ client *http.Client
+}
+
+type lokiQueryRangeResp struct {
+ Status string `json:"status"`
+ Data struct {
+ Result []lokiStream `json:"result"`
+ } `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiLabelsResp struct {
+ Status string `json:"status"`
+ Data []string `json:"data"`
+ Error string `json:"error,omitempty"`
+}
+
+type lokiStr
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4641935569 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
Oxidaner commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4641936749 @robocanic done -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
robocanic commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4639164406 Please merge the branch and resolve the conflicts. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4599847967 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4599588943 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: [PR] feat: mcp-log [dubbo-admin]
sonarqubecloud[bot] commented on PR #1483: URL: https://github.com/apache/dubbo-admin/pull/1483#issuecomment-4593939375 ## [](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) **Quality Gate passed** Issues  [0 New issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=ACCEPTED) Measures  [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo-admin&pullRequest=1483&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_coverage&view=list)  [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_dubbo-admin&pullRequest=1483&metric=new_duplicated_lines_density&view=list) [See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_dubbo-admin&pullRequest=1483) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
