diff --git a/cart/package.json b/cart/package.json index b4d4bf3..fccf50b 100644 --- a/cart/package.json +++ b/cart/package.json @@ -16,6 +16,7 @@ "pino": "^5.10.8", "express-pino-logger": "^4.0.0", "pino-pretty": "^2.5.0", - "@instana/collector": "^1.65.0" + "@instana/collector": "^1.65.0", + "prom-client": "^11.5.3" } } diff --git a/cart/server.js b/cart/server.js index aef2db7..00e6942 100644 --- a/cart/server.js +++ b/cart/server.js @@ -13,6 +13,16 @@ const bodyParser = require('body-parser'); const express = require('express'); const pino = require('pino'); const expPino = require('express-pino-logger'); +// Prometheus +const promClient = require('prom-client'); +const Registry = promClient.Registry; +const register = new Registry(); +const counter = new promClient.Counter({ + name: 'items_added', + help: 'running count of items added to cart', + registers: [register] +}); + var redisConnected = false; @@ -49,6 +59,12 @@ app.get('/health', (req, res) => { res.json(stat); }); +// Prometheus +app.get('/metrics', (req, res) => { + res.header('Content-Type', 'text/plain'); + res.send(register.metrics()); +}); + // get cart with id app.get('/cart/:id', (req, res) => { @@ -165,6 +181,7 @@ app.get('/add/:id/:sku/:qty', (req, res) => { // save the new cart saveCart(req.params.id, cart).then((data) => { + counter.inc(qty); res.json(cart); }).catch((err) => { req.log.error(err); diff --git a/payment/payment.py b/payment/payment.py index 20302b4..f32d801 100644 --- a/payment/payment.py +++ b/payment/payment.py @@ -9,16 +9,28 @@ import traceback import opentracing as ot import opentracing.ext.tags as tags from flask import Flask +from flask import Response from flask import request from flask import jsonify from rabbitmq import Publisher +# Prometheus +import prometheus_client +from prometheus_client import Counter, Histogram app = Flask(__name__) +app.logger.setLevel(logging.INFO) CART = os.getenv('CART_HOST', 'cart') USER = os.getenv('USER_HOST', 'user') PAYMENT_GATEWAY = os.getenv('PAYMENT_GATEWAY', 'https://paypal.com/') +# Prometheus +PromMetrics = {} +PromMetrics['SOLD_COUNTER'] = Counter('sold_count', 'Running count of items sold') +PromMetrics['AUS'] = Histogram('units_sold', 'Avergae Unit Sale', buckets=(1, 2, 5, 10, 100)) +PromMetrics['AVS'] = Histogram('cart_value', 'Avergae Value Sale', buckets=(100, 200, 500, 1000, 2000, 5000, 10000)) + + @app.errorhandler(Exception) def exception_handler(err): app.logger.error(str(err)) @@ -28,6 +40,16 @@ def exception_handler(err): def health(): return 'OK' +# Prometheus +@app.route('/metrics', methods=['GET']) +def metrics(): + res = [] + for m in PromMetrics.values(): + res.append(prometheus_client.generate_latest(m)) + + return Response(res, mimetype='text/plain') + + @app.route('/pay/', methods=['POST']) def pay(id): app.logger.info('payment for {}'.format(id)) @@ -71,6 +93,13 @@ def pay(id): if req.status_code != 200: return 'payment error', req.status_code + # Prometheus + # items purchased + item_count = countItems(cart.get('items', [])) + PromMetrics['SOLD_COUNTER'].inc(item_count) + PromMetrics['AUS'].observe(item_count) + PromMetrics['AVS'].observe(cart.get('total', 0)) + # Generate order id orderid = str(uuid.uuid4()) queueOrder({ 'orderid': orderid, 'user': id, 'cart': cart }) @@ -133,6 +162,15 @@ def queueOrder(order): publisher.publish(order, headers) +def countItems(items): + count = 0 + for item in items: + if item.get('sku') != 'SHIP': + count += item.get('qty') + + return count + + # RabbitMQ publisher = Publisher(app.logger) @@ -140,9 +178,6 @@ if __name__ == "__main__": sh = logging.StreamHandler(sys.stdout) sh.setLevel(logging.INFO) fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') - #sh.setFormatter(fmt) - #app.logger.addHandler(sh) - app.logger.setLevel(logging.INFO) app.logger.info('Payment gateway {}'.format(PAYMENT_GATEWAY)) port = int(os.getenv("SHOP_PAYMENT_PORT", "8080")) app.logger.info('Starting on port {}'.format(port)) diff --git a/payment/requirements.txt b/payment/requirements.txt index e177c38..e888cba 100644 --- a/payment/requirements.txt +++ b/payment/requirements.txt @@ -2,4 +2,5 @@ uwsgi Flask requests pika +prometheus_client instana