Monitoring Angular frontend with Prometheus
Asked Answered
M

2

8

I am currently using Prometheus to monitor my Java-backend with health checks & different counters, it works great!

But, I'm struggling to find information on how I could do the same for my frontend which is written in Angular (TypeScript). Has anyone done something similar before?

Myself answered 18/2, 2021 at 11:24 Comment(6)
Do I understad you correctly that you want to monitor the javascript running in the browser of the users? Or do you want to monitor the HTTP server serving the HTML, Javascript and the other resources?Nelia
I'm also trying to discover the same thing. I want to monitor the HTTP server serving HTML, js and resources.Lapidify
What HTTP server is serving your HTML/JS? prom-client is the Node Prometheus client (which is used by express-prometheus): github.com/siimon/prom-client - If you're using another language, there are a number of different client libraries: prometheus.io/docs/instrumenting/clientlibsVanpelt
I think this repo has a demo github.com/deibl/Prometheus-AngularKhudari
@Vanpelt I'm using NGINX to serve an Angular 8 builded projectLapidify
@Khudari this uses a Java component. It doesn't export metrics through AngularLapidify
D
0

this is an example of how one would monitor such use case:

using this file I'm setting up my front application and the nginx prometheus exporter to expose the Prometheus metrics in the appropriate format: docker-compose.yml

version: "3.9"
services:
  web:
    build: .
    ports:
      - "3000:3000"
  nginx-exporter:
    image: "nginx/nginx-prometheus-exporter:latest"
    command: ["-nginx.scrape-uri=http://web:3000/metrics"]
    ports:
      - "9113:9113"

add this section to your nginx.conf file

location /metrics {
    stub_status on;
}

as part of the whole file:

pid /tmp/nginx.pid;

#Provides the configuration file context in which the directives that affect connection processing are specified.
events {
    # Sets the maximum number of simultaneous connections that can be opened by a worker process.
    worker_connections 8000;
    # Tells the worker to accept multiple connections at a time
    multi_accept on;
}

http {
    # what times to include
    include       /etc/nginx/mime.types;
    # what is the default one
    default_type  application/octet-stream;

    # Sets the path, format, and configuration for a buffered log write
    log_format compression '$remote_addr - $remote_user [$time_local] '
        '"$request" $status $upstream_addr '
        '"$http_referer" "$http_user_agent"';

    server {
        # listen on port 3000
        listen 3000;
        # save logs here
        access_log /var/log/nginx/access.log compression;

        # where the root here
        root /usr/share/nginx/html;
        # what file to server as index
        index index.html index.htm;

        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to redirecting to index.html
            try_files $uri $uri/ /index.html;
        }
        
        location /metrics {
            stub_status on;
        }

        # Media: images, icons, video, audio, HTC
        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
          expires 1M;
          access_log off;
          add_header Cache-Control "public";
        }

        # Javascript and CSS files
        location ~* \.(?:css|js)$ {
            try_files $uri =404;
            expires 1y;
            access_log off;
            add_header Cache-Control "public";
        }

        # Any route containing a file extension (e.g. /devicesfile.js)
        location ~ ^.+\..+$ {
            try_files $uri =404;
        }
    }
}

then in your prometheus configuration file add this new job:

  - job_name: 'nginx'
    static_configs:
    - targets: ['<machine_ip>:9113']

And here you can find an example dashboard

Dekaliter answered 14/9, 2021 at 15:5 Comment(0)
G
0

To monitor/count events on the frontend you can run a "frontend-metrics-server" where your frontend can submit the events to be counted with Prometheus.

This is a simple implementation which also allows tracking errors from the frontend:

@RestController
@Slf4j
public class CounterController {
    private static final Map<String, Gauge> EVENT_COUNTERS = new ConcurrentHashMap<>();

    private static final Counter ERROR_COUNTER = Counter.build()
            .name("error_counter")
            .help("Number of errors received")
            .register();

    @PostMapping("/updateCounter")
    public void updateCounter(@RequestBody CounterUpdateRequest request) {
        Gauge gauge = EVENT_COUNTERS.computeIfAbsent(request.name(), name ->
                Gauge.build()
                        .name("event_counter_" + name)
                        .help("Number of " + name + " events received")
                        .register()
        );
        gauge.inc(request.amount());
        log.info("Metric {} increased by {} through user {}", request.name(), request.amount(), addTheUserIdHere);
    }

    @PostMapping("/reportError")
    public void reportError(@RequestBody ErrorReportRequest request) {
        ERROR_COUNTER.inc();
        log.error("User {}: {}", addTheUserIdHere, request.message());
    }

    public record CounterUpdateRequest(String name, int amount) {}

    public record ErrorReportRequest(String message) {}
}

Of course, you can add additional parameters or types of metrics.

Keep in mind, that the API could be called by your users with other data which can "soil" your metrics and logs.

Grosmark answered 13/3, 2024 at 7:42 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.