Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add monitor #1171

Closed
wants to merge 451 commits into from
Closed

feat: add monitor #1171

wants to merge 451 commits into from

Conversation

Redish101
Copy link
Contributor

@Redish101 Redish101 commented Sep 7, 2024

Description

Migrate monitor middleware from fiber v2 to v3. See at gofiber/fiber#3125

Summary by CodeRabbit

  • New Features

    • Introduced a structured template for automated release notes management in GitHub.
    • Added a GitHub Actions workflow to automate the drafting of release notes.
    • Implemented a web-based monitoring interface for system metrics with real-time updates.
    • Developed a middleware for monitoring system and process statistics, providing JSON and HTML responses.
  • Documentation

    • Added a comprehensive README file for the "monitor" component to enhance user guidance and documentation structure.

ReneWerner87 and others added 30 commits March 7, 2024 14:26
Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.82.0 to 2.84.0.
- [Release notes](https://github.com/casbin/casbin/releases)
- [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json)
- [Commits](casbin/casbin@v2.82.0...v2.84.0)

---
updated-dependencies:
- dependency-name: github.com/casbin/casbin/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
…sbin/github.com/casbin/casbin/v2-2.84.0

build(deps): bump github.com/casbin/casbin/v2 from 2.82.0 to 2.84.0 in /casbin
Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.84.0 to 2.84.1.
- [Release notes](https://github.com/casbin/casbin/releases)
- [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json)
- [Commits](casbin/casbin@v2.84.0...v2.84.1)

---
updated-dependencies:
- dependency-name: github.com/casbin/casbin/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
…sbin/github.com/casbin/casbin/v2-2.84.1

build(deps): bump github.com/casbin/casbin/v2 from 2.84.0 to 2.84.1 in /casbin
Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
…bernewrelic/google.golang.org/protobuf-1.33.0

build(deps): bump google.golang.org/protobuf from 1.30.0 to 1.33.0 in /fibernewrelic
…afiber/google.golang.org/protobuf-1.33.0

build(deps): bump google.golang.org/protobuf from 1.31.0 to 1.33.0 in /opafiber
Update Swagger middleware documentation
Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.84.1 to 2.85.0.
- [Release notes](https://github.com/casbin/casbin/releases)
- [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json)
- [Commits](casbin/casbin@v2.84.1...v2.85.0)

---
updated-dependencies:
- dependency-name: github.com/casbin/casbin/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
…sbin/github.com/casbin/casbin/v2-2.85.0

build(deps): bump github.com/casbin/casbin/v2 from 2.84.1 to 2.85.0 in /casbin
[otelfiber] Allow for disabling client IP collection in traces
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.6.0 to 2.0.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](dependabot/fetch-metadata@v1.6.0...v2.0.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
…s/dependabot/fetch-metadata-2.0.0

build(deps): bump dependabot/fetch-metadata from 1.6.0 to 2.0.0
Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.52.2 to 2.52.3.
- [Release notes](https://github.com/gofiber/fiber/releases)
- [Commits](gofiber/fiber@v2.52.2...v2.52.3)

---
updated-dependencies:
- dependency-name: github.com/gofiber/fiber/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
…elfiber/example/github.com/gofiber/fiber/v2-2.52.3

build(deps): bump github.com/gofiber/fiber/v2 from 2.52.2 to 2.52.3 in /otelfiber/example
Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.52.2 to 2.52.3.
- [Release notes](https://github.com/gofiber/fiber/releases)
- [Commits](gofiber/fiber@v2.52.2...v2.52.3)

---
updated-dependencies:
- dependency-name: github.com/gofiber/fiber/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
…sbin/github.com/gofiber/fiber/v2-2.52.3

build(deps): bump github.com/gofiber/fiber/v2 from 2.52.2 to 2.52.3 in /casbin
liaohongxing and others added 13 commits August 26, 2024 13:32
Add Note for WebSocket subprotocols
Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.98.0 to 2.99.0.
- [Release notes](https://github.com/casbin/casbin/releases)
- [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json)
- [Commits](casbin/casbin@v2.98.0...v2.99.0)

---
updated-dependencies:
- dependency-name: github.com/casbin/casbin/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Bumps [github.com/felixge/fgprof](https://github.com/felixge/fgprof) from 0.9.4 to 0.9.5.
- [Release notes](https://github.com/felixge/fgprof/releases)
- [Commits](felixge/fgprof@v0.9.4...v0.9.5)

---
updated-dependencies:
- dependency-name: github.com/felixge/fgprof
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
…sbin/github.com/casbin/casbin/v2-2.99.0

build(deps): bump github.com/casbin/casbin/v2 from 2.98.0 to 2.99.0 in /casbin
…prof/github.com/felixge/fgprof-0.9.5

build(deps): bump github.com/felixge/fgprof from 0.9.4 to 0.9.5 in /fgprof
SocketIO: Change isAlive to atomic update to solve the high concurrency problem
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.27.0.
- [Commits](golang/crypto@v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
…seto/golang.org/x/crypto-0.27.0

build(deps): bump golang.org/x/crypto from 0.26.0 to 0.27.0 in /paseto
@Redish101 Redish101 requested a review from a team as a code owner September 7, 2024 23:06
@Redish101 Redish101 requested review from gaby, sixcolors, ReneWerner87 and efectn and removed request for a team September 7, 2024 23:06
@github-actions github-actions bot added the ✏️ Feature New feature or request label Sep 7, 2024
Copy link
Contributor

coderabbitai bot commented Sep 7, 2024

Walkthrough

The recent changes introduce a structured approach to managing release notes and system monitoring within a GitHub repository. A new YAML configuration file, .github/release-drafter-monitor.yml, has been created to define templates for release notes, including versioning, changelog categories, and contributor exclusions. This configuration facilitates automated tracking and filtering of changes, enhancing clarity in communication. Additionally, a GitHub Actions workflow named "Release Drafter Casbin" has been implemented to automate the drafting of release notes based on changes detected in the 'monitor/**' directory.

Several new Go files have been added to implement a middleware for monitoring system metrics using the Fiber web framework. This includes a configuration structure, a web-based interface for displaying metrics, and middleware for collecting and responding with system statistics. Each component is designed to work together, ensuring that the monitoring system is robust and user-friendly.

Changes

Files Change Summary
.github/release-drafter-monitor.yml Introduced YAML configuration for release notes management, including templates and categories.
.github/workflows/release-drafter-monitor.yml Added GitHub Actions workflow to automate release note drafting based on changes in the monitor directory.
monitor/README.md Created comprehensive documentation for the monitor component, including installation and usage details.
monitor/config.go Defined configuration structure for middleware with default settings and validation.
monitor/index.go Implemented web interface for monitoring metrics, including dynamic HTML and JavaScript updates.
monitor/monitor.go Developed middleware for monitoring system statistics, including CPU and RAM usage.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Middleware
    participant Metrics
    participant Config

    User->>Middleware: Request Metrics
    Middleware->>Config: Retrieve Configuration
    Config-->>Middleware: Return Config
    Middleware->>Metrics: Update Statistics
    Metrics-->>Middleware: Return Metrics Data
    Middleware-->>User: Respond with Metrics
Loading

🐇 In the meadow, changes bloom,
A drafter’s song dispels the gloom.
With metrics bright and notes so clear,
We hop along, spreading cheer!
Let’s celebrate this joyful day,
For every change, we leap and play! 🌼✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Outside diff range, codebase verification and nitpick comments (1)
.github/release-drafter-monitor.yml (1)

1-50: Well-configured Release Drafter setup.

The configuration for the Release Drafter GitHub Action is well-structured and aligns with the PR's objectives. It effectively automates the release note drafting process, which is crucial for maintaining clear communication about changes.

Consider adding more specific documentation or comments within the YAML file to explain the purpose of each configuration section, especially for new contributors or external collaborators who might interact with this setup.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 30766e8 and cff0f5a.

Files ignored due to path filters (2)
  • monitor/go.mod is excluded by !**/*.mod
  • monitor/go.sum is excluded by !**/*.sum, !**/*.sum
Files selected for processing (6)
  • .github/release-drafter-monitor.yml (1 hunks)
  • .github/workflows/release-drafter-monitor.yml (1 hunks)
  • monitor/README.md (1 hunks)
  • monitor/config.go (1 hunks)
  • monitor/index.go (1 hunks)
  • monitor/monitor.go (1 hunks)
Files skipped from review due to trivial changes (2)
  • .github/workflows/release-drafter-monitor.yml
  • monitor/README.md
Additional comments not posted (1)
monitor/index.go (1)

9-15: Struct viewBag is well-defined.

The struct fields are appropriately named and match the parameters used in the HTML template. This struct will facilitate passing configuration data to the template effectively.

Comment on lines +9 to +132
// Optional. Default: empty
CustomHead string

// FontURL for specify font resource path or URL . also you can use relative path
//
// Optional. Default: https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap
FontURL string

// ChartJsURL for specify ChartJS library path or URL . also you can use relative path
//
// Optional. Default: https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.bundle.min.js
ChartJsURL string // TODO: Rename to "ChartJSURL" in v3

index string
}

var ConfigDefault = Config{
Title: defaultTitle,
Refresh: defaultRefresh,
FontURL: defaultFontURL,
ChartJsURL: defaultChartJSURL,
CustomHead: defaultCustomHead,
APIOnly: false,
Next: nil,
index: newIndex(viewBag{
defaultTitle,
defaultRefresh,
defaultFontURL,
defaultChartJSURL,
defaultCustomHead,
}),
}

func configDefault(config ...Config) Config {
// Users can change ConfigDefault.Title/Refresh which then
// become incompatible with ConfigDefault.index
if ConfigDefault.Title != defaultTitle ||
ConfigDefault.Refresh != defaultRefresh ||
ConfigDefault.FontURL != defaultFontURL ||
ConfigDefault.ChartJsURL != defaultChartJSURL ||
ConfigDefault.CustomHead != defaultCustomHead {
if ConfigDefault.Refresh < minRefresh {
ConfigDefault.Refresh = minRefresh
}
// update default index with new default title/refresh
ConfigDefault.index = newIndex(viewBag{
ConfigDefault.Title,
ConfigDefault.Refresh,
ConfigDefault.FontURL,
ConfigDefault.ChartJsURL,
ConfigDefault.CustomHead,
})
}

// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}

// Override default config
cfg := config[0]

// Set default values
if cfg.Title == "" {
cfg.Title = ConfigDefault.Title
}

if cfg.Refresh == 0 {
cfg.Refresh = ConfigDefault.Refresh
}
if cfg.FontURL == "" {
cfg.FontURL = defaultFontURL
}

if cfg.ChartJsURL == "" {
cfg.ChartJsURL = defaultChartJSURL
}
if cfg.Refresh < minRefresh {
cfg.Refresh = minRefresh
}

if cfg.Next == nil {
cfg.Next = ConfigDefault.Next
}

if !cfg.APIOnly {
cfg.APIOnly = ConfigDefault.APIOnly
}

// update cfg.index with custom title/refresh
cfg.index = newIndex(viewBag{
title: cfg.Title,
refresh: cfg.Refresh,
fontURL: cfg.FontURL,
chartJSURL: cfg.ChartJsURL,
customHead: cfg.CustomHead,
})

return cfg
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robust configuration structure for monitor middleware.

The Config struct is well-documented and designed to be flexible with sensible defaults and optional overrides. This setup ensures that the middleware can be easily configured to meet different requirements.

Consider future-proofing the code by introducing versioning for the configuration structure. This could help manage changes more effectively as the middleware evolves, especially if breaking changes are introduced in future versions.

Comment on lines +55 to +137
// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
// Set default config
cfg := configDefault(config...)

// Start routine to update statistics
once.Do(func() {
p, _ := process.NewProcess(int32(os.Getpid())) //nolint:errcheck // TODO: Handle error
numcpu := runtime.NumCPU()
updateStatistics(p, numcpu)

go func() {
for {
time.Sleep(cfg.Refresh)

updateStatistics(p, numcpu)
}
}()
})

// Return new handler
//nolint:errcheck // Ignore the type-assertion errors
return func(c fiber.Ctx) error {
// Don't execute middleware if Next returns true
if cfg.Next != nil && cfg.Next(&c) {
return c.Next()
}

if c.Method() != fiber.MethodGet {
return fiber.ErrMethodNotAllowed
}
if c.Get(fiber.HeaderAccept) == fiber.MIMEApplicationJSON || cfg.APIOnly {
mutex.Lock()
data.PID.CPU, _ = monitPIDCPU.Load().(float64)
data.PID.RAM, _ = monitPIDRAM.Load().(uint64)
data.PID.Conns, _ = monitPIDConns.Load().(int)

data.OS.CPU, _ = monitOSCPU.Load().(float64)
data.OS.RAM, _ = monitOSRAM.Load().(uint64)
data.OS.TotalRAM, _ = monitOSTotalRAM.Load().(uint64)
data.OS.LoadAvg, _ = monitOSLoadAvg.Load().(float64)
data.OS.Conns, _ = monitOSConns.Load().(int)
mutex.Unlock()
return c.Status(fiber.StatusOK).JSON(data)
}
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).SendString(cfg.index)
}
}

func updateStatistics(p *process.Process, numcpu int) {
pidCPU, err := p.Percent(0)
if err == nil {
monitPIDCPU.Store(pidCPU / float64(numcpu))
}

if osCPU, err := cpu.Percent(0, false); err == nil && len(osCPU) > 0 {
monitOSCPU.Store(osCPU[0])
}

if pidRAM, err := p.MemoryInfo(); err == nil && pidRAM != nil {
monitPIDRAM.Store(pidRAM.RSS)
}

if osRAM, err := mem.VirtualMemory(); err == nil && osRAM != nil {
monitOSRAM.Store(osRAM.Used)
monitOSTotalRAM.Store(osRAM.Total)
}

if loadAvg, err := load.Avg(); err == nil && loadAvg != nil {
monitOSLoadAvg.Store(loadAvg.Load1)
}

pidConns, err := net.ConnectionsPid("tcp", p.Pid)
if err == nil {
monitPIDConns.Store(len(pidConns))
}

osConns, err := net.Connections("tcp")
if err == nil {
monitOSConns.Store(len(osConns))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Effective concurrency handling but needs better error management.

The middleware effectively handles concurrency using atomic values and mutexes, ensuring thread-safe operations. This is crucial for the accurate and reliable functioning of the monitoring system.

However, the error handling is insufficient, particularly in the updateStatistics function where errors are noted but not handled. Consider implementing comprehensive error handling to prevent potential issues in production environments.

Implement error handling in the updateStatistics function. For example, log errors or retry operations when encountering failures to read system statistics.

Comment on lines +17 to +28
// returns index with new title/refresh
func newIndex(dat viewBag) string {
timeout := dat.refresh.Milliseconds() - timeoutDiff
if timeout < timeoutDiff {
timeout = timeoutDiff
}
ts := strconv.FormatInt(timeout, 10)
replacer := strings.NewReplacer("$TITLE", dat.title, "$TIMEOUT", ts,
"$FONT_URL", dat.fontURL, "$CHART_JS_URL", dat.chartJSURL, "$CUSTOM_HEAD", dat.customHead,
)
return replacer.Replace(indexHTML)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarify the use of timeoutDiff.

The function newIndex uses timeoutDiff to adjust the refresh timeout, but it's unclear where timeoutDiff is defined or its purpose. Please add comments to clarify its use and ensure it is defined appropriately.

Comment on lines +30 to +271
tooltips: { enabled: false },
responsive: true,
maintainAspectRatio: false,
animation: false
};
const cpuMetric = document.querySelector('#cpuMetric');
const ramMetric = document.querySelector('#ramMetric');
const rtimeMetric = document.querySelector('#rtimeMetric');
const connsMetric = document.querySelector('#connsMetric');

const cpuChartCtx = document.querySelector('#cpuChart').getContext('2d');
const ramChartCtx = document.querySelector('#ramChart').getContext('2d');
const rtimeChartCtx = document.querySelector('#rtimeChart').getContext('2d');
const connsChartCtx = document.querySelector('#connsChart').getContext('2d');

const cpuChart = createChart(cpuChartCtx);
const ramChart = createChart(ramChartCtx);
const rtimeChart = createChart(rtimeChartCtx);
const connsChart = createChart(connsChartCtx);

const charts = [cpuChart, ramChart, rtimeChart, connsChart];

function createChart(ctx) {
return new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: '',
data: [],
lineTension: 0.2,
pointRadius: 0,
}]
},
options
});
}
ramChart.data.datasets.push({
data: [],
lineTension: 0.2,
pointRadius: 0,
backgroundColor: 'rgba(255, 200, 0, .6)',
borderColor: 'rgba(255, 150, 0, .8)',
})
ramChart.data.datasets.push({
data: [],
lineTension: 0.2,
pointRadius: 0,
backgroundColor: 'rgba(0, 255, 0, .4)',
borderColor: 'rgba(0, 200, 0, .8)',
})
function update(json, rtime) {
cpu = json.pid.cpu.toFixed(1);
cpuOS = json.os.cpu.toFixed(1);

cpuMetric.innerHTML = cpu + '% <span>' + cpuOS + '%</span>';
ramMetric.innerHTML = formatBytes(json.pid.ram) + '<span> / </span><span class="ram_os">' + formatBytes(json.os.ram) +
'<span><span> / </span><span class="ram_total">' + formatBytes(json.os.total_ram) + '</span>';
rtimeMetric.innerHTML = rtime + 'ms <span>client</span>';
connsMetric.innerHTML = json.pid.conns + ' <span>' + json.os.conns + '</span>';

cpuChart.data.datasets[0].data.push(cpu);
ramChart.data.datasets[2].data.push((json.os.total_ram / 1e6).toFixed(2));
ramChart.data.datasets[1].data.push((json.os.ram / 1e6).toFixed(2));
ramChart.data.datasets[0].data.push((json.pid.ram / 1e6).toFixed(2));
rtimeChart.data.datasets[0].data.push(rtime);
connsChart.data.datasets[0].data.push(json.pid.conns);

const timestamp = new Date().getTime();

charts.forEach(chart => {
if (chart.data.labels.length > 50) {
chart.data.datasets.forEach(function (dataset) { dataset.data.shift(); });
chart.data.labels.shift();
}
chart.data.labels.push(timestamp);
chart.update();
});
setTimeout(fetchJSON, $TIMEOUT)
}
function fetchJSON() {
var t1 = ''
var t0 = performance.now()
fetch(window.location.href, {
headers: { 'Accept': 'application/json' },
credentials: 'same-origin'
})
.then(res => {
t1 = performance.now()
return res.json()
})
.then(res => { update(res, Math.round(t1 - t0)) })
.catch(console.error);
}
fetchJSON()
</script>
</body>
</html>
`
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constants and HTML template are well-defined but consider improvements.

The constants provide sensible default values and the HTML template is comprehensive. However, consider the following improvements:

  • Security: Ensure that any user-generated content inserted into the HTML is properly sanitized to prevent XSS attacks.
  • Maintainability: Large HTML blocks within Go code can be hard to maintain. Consider loading HTML from a separate file or using a templating engine.

Comment on lines +140 to +267
},
gridlines: { display: false }
}]
},
tooltips: { enabled: false },
responsive: true,
maintainAspectRatio: false,
animation: false
};
const cpuMetric = document.querySelector('#cpuMetric');
const ramMetric = document.querySelector('#ramMetric');
const rtimeMetric = document.querySelector('#rtimeMetric');
const connsMetric = document.querySelector('#connsMetric');

const cpuChartCtx = document.querySelector('#cpuChart').getContext('2d');
const ramChartCtx = document.querySelector('#ramChart').getContext('2d');
const rtimeChartCtx = document.querySelector('#rtimeChart').getContext('2d');
const connsChartCtx = document.querySelector('#connsChart').getContext('2d');

const cpuChart = createChart(cpuChartCtx);
const ramChart = createChart(ramChartCtx);
const rtimeChart = createChart(rtimeChartCtx);
const connsChart = createChart(connsChartCtx);

const charts = [cpuChart, ramChart, rtimeChart, connsChart];

function createChart(ctx) {
return new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: '',
data: [],
lineTension: 0.2,
pointRadius: 0,
}]
},
options
});
}
ramChart.data.datasets.push({
data: [],
lineTension: 0.2,
pointRadius: 0,
backgroundColor: 'rgba(255, 200, 0, .6)',
borderColor: 'rgba(255, 150, 0, .8)',
})
ramChart.data.datasets.push({
data: [],
lineTension: 0.2,
pointRadius: 0,
backgroundColor: 'rgba(0, 255, 0, .4)',
borderColor: 'rgba(0, 200, 0, .8)',
})
function update(json, rtime) {
cpu = json.pid.cpu.toFixed(1);
cpuOS = json.os.cpu.toFixed(1);

cpuMetric.innerHTML = cpu + '% <span>' + cpuOS + '%</span>';
ramMetric.innerHTML = formatBytes(json.pid.ram) + '<span> / </span><span class="ram_os">' + formatBytes(json.os.ram) +
'<span><span> / </span><span class="ram_total">' + formatBytes(json.os.total_ram) + '</span>';
rtimeMetric.innerHTML = rtime + 'ms <span>client</span>';
connsMetric.innerHTML = json.pid.conns + ' <span>' + json.os.conns + '</span>';

cpuChart.data.datasets[0].data.push(cpu);
ramChart.data.datasets[2].data.push((json.os.total_ram / 1e6).toFixed(2));
ramChart.data.datasets[1].data.push((json.os.ram / 1e6).toFixed(2));
ramChart.data.datasets[0].data.push((json.pid.ram / 1e6).toFixed(2));
rtimeChart.data.datasets[0].data.push(rtime);
connsChart.data.datasets[0].data.push(json.pid.conns);

const timestamp = new Date().getTime();

charts.forEach(chart => {
if (chart.data.labels.length > 50) {
chart.data.datasets.forEach(function (dataset) { dataset.data.shift(); });
chart.data.labels.shift();
}
chart.data.labels.push(timestamp);
chart.update();
});
setTimeout(fetchJSON, $TIMEOUT)
}
function fetchJSON() {
var t1 = ''
var t0 = performance.now()
fetch(window.location.href, {
headers: { 'Accept': 'application/json' },
credentials: 'same-origin'
})
.then(res => {
t1 = performance.now()
return res.json()
})
.then(res => { update(res, Math.round(t1 - t0)) })
.catch(console.error);
}
fetchJSON()
</script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JavaScript functionality is effective but consider performance improvements.

The embedded JavaScript effectively updates the monitoring data in real-time. Consider the following performance improvements:

  • Memory Management: Ensure that old data is properly cleared to prevent memory leaks, especially in long-running pages.
  • Error Handling: Improve error handling in the fetchJSON function to manage network errors more gracefully.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cff0f5a and 2a616be.

Files selected for processing (1)
  • monitor/README.md (1 hunks)
Additional context used
LanguageTool
monitor/README.md

[uncategorized] ~36-~36: Possible missing comma found.
Context: ... for specilt font resource path or URL. also you can use relative path. | `htt...

(AI_HYDRA_LEO_MISSING_COMMA)

Markdownlint
monitor/README.md

16-16: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)

Additional comments not posted (5)
monitor/README.md (5)

7-10: Review badges for consistency and relevance.

The badges for release, tests, security, and linting are included. Ensure these URLs are correct and relevant to the project. It's important that these badges reflect the actual status of the project and are linked to the correct actions.


14-19: Installation instructions are clear and concise.

The installation instructions for Fiber v3 and the monitor middleware are straightforward. However, it's crucial to ensure that these commands are tested and work as expected, especially since this is a migration to a new major version.

Tools
Markdownlint

16-16: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)


43-61: Example usage is clear and demonstrates basic setup.

The example code provided demonstrates how to set up the monitor middleware in a Fiber application. Ensure that this example is functional and represents best practices for using the middleware.

Verification successful

Example usage is functional and follows best practices.

The example code in the README.md correctly demonstrates how to set up the monitor middleware in a Fiber application. The imports and middleware setup are consistent with the codebase and align with standard practices for using middleware in Fiber applications.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the example usage in the Go source code.

# Test: Check if the example usage is functional and follows best practices.
echo "Verify the example usage for setting up the monitor middleware."

Length of output: 136


Script:

#!/bin/bash
# Check for the presence of the fiber and monitor package imports in the codebase.
rg 'github.com/gofiber/fiber/v3' -A 5
rg 'github.com/gofiber/contrib/monitor' -A 5

Length of output: 4908


23-25: Check the function signature for accuracy.

The function signature for creating a new monitor instance is provided. It's important to verify that this signature matches the actual implementation in the Go source code to avoid discrepancies.

Verification successful

Function signature is accurate.

The function signature for monitor.New in the README matches the actual implementation in the Go source code. The Config struct is defined in monitor/config.go, aligning with the usage of monitor.Config in the README. No discrepancies were found.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the function signature for `monitor.New`.

# Test: Search for the function signature in the Go source code.
ast-grep --lang go --pattern $'func New($_ ...Config) fiber.Handler'

Length of output: 28270


Script:

#!/bin/bash
# Description: Check if `Config` is defined or aliased as `monitor.Config` in the Go files.

# Search for the definition or aliasing of `Config` as `monitor.Config`.
rg 'type Config|alias Config' --type go -A 2

Length of output: 2460


29-37: Review configuration options for clarity and correctness.

The configuration table is well-structured, providing clear information about each configurable property. However, ensure that all default values and types are correctly documented and match the actual code implementation.

Verification successful

Configuration Options Verified Successfully

The configuration options in the documentation match the actual code implementation in terms of types and default values. No discrepancies were found.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the configuration options in the Go source code.

# Test: Check if the configuration options match the documentation.
echo "Verify the following configuration options:"
echo "Title, Refresh, APIOnly, Next, CustomHead, FontURL, ChartJsURL"

Length of output: 231


Script:

#!/bin/bash
# Description: Search for the configuration options in the Go source code to verify their types and default values.

# Search for the definition of the configuration options in Go files.
ast-grep --lang go --pattern 'Title string' 
ast-grep --lang go --pattern 'Refresh time.Duration' 
ast-grep --lang go --pattern 'APIOnly bool' 
ast-grep --lang go --pattern 'Next func(*fiber.Ctx) bool' 
ast-grep --lang go --pattern 'CustomHead string' 
ast-grep --lang go --pattern 'FontURL string' 
ast-grep --lang go --pattern 'ChartJsURL string' 

Length of output: 2426


Script:

#!/bin/bash
# Description: Use ripgrep to search for the configuration options in the Go source code to verify their types and default values.

# Search for the configuration options in Go files.
rg 'Title' --type go -A 3
rg 'Refresh' --type go -A 3
rg 'APIOnly' --type go -A 3
rg 'Next' --type go -A 3
rg 'CustomHead' --type go -A 3
rg 'FontURL' --type go -A 3
rg 'ChartJsURL' --type go -A 3

Length of output: 27417

Tools
LanguageTool

[uncategorized] ~36-~36: Possible missing comma found.
Context: ... for specilt font resource path or URL. also you can use relative path. | `htt...

(AI_HYDRA_LEO_MISSING_COMMA)

monitor/README.md Show resolved Hide resolved
| APIOnly | `bool` | Whether the service should expose only the montioring API. | `false` |
| Next | `func(c *fiber.Ctx) bool` | Define a function to add custom fields. | `nil` |
| CustomHead | `string` | Custom HTML conde to Head Section(Before End). | `empty` |
| FontURL | `string` | FontURL for specilt font resource path or URL. also you can use relative path. | `https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar correction needed.

There's a grammatical error in the description of FontURL. The sentence should have a comma before "also".

Apply this correction:

- FontURL for specilt font resource path or URL. also you can use relative path.
+ FontURL for specilt font resource path or URL, also you can use relative path.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| FontURL | `string` | FontURL for specilt font resource path or URL. also you can use relative path. | `https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap` |
| FontURL | `string` | FontURL for specilt font resource path or URL, also you can use relative path. | `https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap` |
Tools
LanguageTool

[uncategorized] ~36-~36: Possible missing comma found.
Context: ... for specilt font resource path or URL. also you can use relative path. | `htt...

(AI_HYDRA_LEO_MISSING_COMMA)

| ChartJsURL | `string` | ChartJsURL for specilt chartjs library, path or URL, also you can use relative path. | `https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.bundle.min.js` |

> Because jsdelivr lost their ICP license, so chinese users maybe use other CDNs to load ChartJs library.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not relevant here, it's up to the user to handle their CDN

@Redish101 Redish101 changed the base branch from main to v3-beta September 7, 2024 23:27
@Redish101 Redish101 closed this Sep 7, 2024
@@ -0,0 +1,28 @@
module github.com/gofiber/contrib/monitor

go 1.22.6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be 1.22, without the patch

@@ -0,0 +1,19 @@
name: Release Drafter Casbin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monitor* instead of Casbin

paths:
- 'monitor/**'
jobs:
draft_release_casbin:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monitor instead of Casbin

template: |
$CHANGES

**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...casbin/v$RESOLVED_VERSION
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monitor instead of Casbin

app := fiber.New()

app.Use("/monitor", monitor.New())

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra newline here

})

// Return new handler
//nolint:errcheck // Ignore the type-assertion errors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this "nolint" can be removed

@Redish101
Copy link
Contributor Author

@gaby Sorry, these changes should be committed to the v3-beta branch. Please refer to PR #1172

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✏️ Feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.