Skip to main content

lib in development

Project description

thinknet-observer-python


เป็น library ที่รวบรวมเครื่องมือการทำ observaibility ตาม format ของบริษัท ด้วยภาษา python โดยมีเครื่องมือดังนี้

  • metrics
  • log
  • tracing

Installation

pip install thinknet-observer

Metrics

การเรียกใช้ metrics เพื่อให้ prometheus มาเก็บ (pull) โดยมีวิธีการใช้งานดังนี้:

PrometheusMiddleware()

เป็น Class ที่ return middleware สำหรับเก็บ default metrics

Example

from thinknet_observer import PrometheusMiddleware

# Flask
app = Flask(__name__)
# FastAPI
app = FastAPI()

''' use middleware to collect default metrics '''
# singleprocess mode
middleware = PrometheusMiddleware(app) 
# multiprocess mode
middleware = PrometheusMiddleware(app, is_multiprocessing = True) 

# add exclude (optional)
list_exclude = [{"route": "/healthz"}]
middleware.add_exclude(list_exclude)

extension

Module สำหรับสร้าง custom metrics โดยมีการเรียกใช้งานดังนี้

from thinknet_observer import MetricCollector

โดย custom metrics มีฟังก์ชั่นการทำงาน 4 ประเภทดังนี้

MetricCollector.counter(name, description, label)

เป็น class method สำหรับสร้าง metrics ประเภท counter ซึ่งสามารถเพิ่มค่าได้อย่างเดียว

Parameter

name type description
name String ชื่อของ metrics
description String description ของ metrics
labels Array array of string labels ของ metrics [optional]

Example

# no label
custom_counter = MetricCollector.counter("CUSTOM_COUNTER", "desc of CUSTOM_COUNTER")
custom_counter.inc(1) #เพิ่มค่า 1

# label
custom_counter_label = MetricCollector.counter("CUSTOM_COUNTER", "desc of CUSTOM_COUNTER", ["key1","key2"])
custom_counter_label.labels('value1', 'value2').inc(1)

MetricCollector.gauge(name, description, label)

เป็น class method สำหรับสร้าง metric ประเภท gauge ซึ่งสามารถเพิ่ม/ลดค่าได้

Parameter

name type description
name String ชื่อของ metrics
description String description ของ metrics
labels Array array of string labels ของ metrics [optional]

Example

# no labels
custom_gauge = MetricCollector.gauge(
    "CUSTOM_GAUGE", "desc of CUSTOM_GAUGE",
)
custom_gauge.inc(1) #เพิ่มค่า 1
custom_gauge.dec(5) #ลดค่าลง 5 

#labels
custom_gauge_label = MetricCollector.gauge(
    "CUSTOM_GAUGE", "desc of CUSTOM_GAUGE", ["key1", "key2"]
)
custom_gauge_label.labels('value1', 'value2').inc(1)
custom_gauge_label.labels('value1', 'value2').dec(5)

MetricCollector.histogram(name, description,label, bucket)

เป็น class method สำหรับสร้าง metric ประเภท histogram

Parameter

name type description
name String ชื่อของ metrics
description String description ของ metrics
labels Array array of string labels ของ metrics [optional]
bucket Array array of bucket for histogram [optional]

Example

# no labels
custom_histogram = MetricCollector.histogram(
    "CUSTOM_HISTOGRAM", "desc of CUSTOM_HISTOGRAM",
)
custom_histogram.observe(20)

# labels
custom_histogram = MetricCollector.histogram(
    "CUSTOM_HISTOGRAM", "desc of CUSTOM_HISTOGRAM", ["key1", "key2"]
)
custom_histogram.labels('value1', 'value2').observe(20)

MetricCollector.summary(name, description, label)

เป็น class method สำหรับสร้าง metric ประเภท summary

Parameter

name type description
name String ชื่อของ metrics
description String description ของ metrics
labels Array array of string labels ของ metrics [optional]

Example

# no labels
custom_summary = MetricCollector.summary(
    "CUSTOM_SUMMARY", "desc of CUSTOM_SUMMARY"
)
custom_summary.observe(10)

# labels
custom_summary_label = MetricCollector.summary(
    "CUSTOM_SUMMARY", "desc of CUSTOM_SUMMARY", ["key1", "key2"]
)
custom_summary_label.labels('value1', 'value2').observe(10)

multiprocess mode

กรณีรันเป็น multiprocess mode ให้เพิ่ม environment: PROMETHEUS_MULTIPROC_DIR ด้วย

PROMETHEUS_MULTIPROC_DIR=./prometheus_multiproc/ (folder for multiprocess metrics)

using gunicorn (Flask)

กรณีรันด้วย gunicorn แบบ multiprocess mode ให้เพิ่ม file: gunicorn.config.py ที่ root path ด้วย

import os

from pathlib import Path
from multiprocessing import cpu_count
from os import environ
from prometheus_client import multiprocess
from thinknet_observer import clear_multiproc_dir

def child_exit(server, worker):
    multiprocess.mark_process_dead(worker.pid)

def max_workers():    
    return cpu_count()

clear_multiproc_dir()

ref: https://github.com/prometheus/client_python


Log

log ของ thinknet_observer มีทั้งหมดสามแบบ logging, analyzer และ cronlogger โดยใช้แตกต่างกันดังต่อไปนี้

logging()

เป็น class method สำหรับใช้ logging เราจะใช้เมื่อต้องการ log เพื่อแสดงข้อความเกี่ยวกับการทำงานของระบบ (มักใช้กับ project ที่เป็น Service) และข้อความนั้น ๆ เป็น String โดย Log ที่ได้จะแสดงข้อมูลดังต่อไปนี้

Field Name Description
timestamp เวลาที่ทำการสร้าง log โดยจะอยู่ใน Format %Y-%m-%dT%H:%M:%S
level ระดับของ Log (สามารถอ่านเพิ่มเติม log level)
message ข้อความที่ต้องการจะแสดง
log.source ที่มาต้นทางของ log นั้น ๆ
log.version เวอร์ชั่นของ log

วิธีการเรียกใช้งาน

from thinknet_observer import Logger
# Create instance
log = Logger.logging()
# Generate Log
log.error(message= "Error Message")
# {'timestamp':'2022-03-30T13:28:22Z','level':'ERROR','message':'Error Message','log.source':'application','log.version':1}

analyzer()

log ประเภทนี้เหมือนกับประเภทก่อนหน้าแต่ในการรับ message จะสามารถรับ message ที่เป็น Json ได้ (มักใช้กับ project ที่เป็น Service)โดย Log ที่ได้จะแสดงข้อมูลดังต่อไปนี้

Field Name Description
timestamp เวลาที่ทำการสร้าง log โดยจะอยู่ใน Format %Y-%m-%dT%H:%M:%S
level ระดับของ Log (สามารถอ่านเพิ่มเติม log level)
message ข้อความที่ต้องการจะแสดง
log.source ที่มาต้นทางของ log นั้น ๆ
log.version เวอร์ชั่นของ log

ลักษณะของ message ที่ต้องการ log

{
   "httpStatus": 4xx, 5xx (int)[optional]
   "serviceCode": key ที่สามารถสื่อความหมายชัดเจน (string
   "description": message จริงๆของระบบ (ถ้าไม่มีค่อยกำหนดเอง) (string)
   "traceID": ได้จาก headers (string)
   "payload": Stringify({}) [optional]
 } 

วิธีการเรียกใช้งาน

from thinknet_observer import Logger
# Create instance
analyzelog = Logger.analyzer()
# Generate Log
analyzelog.error(message= {"index": 0, "data": []})
# {'timestamp':'2022-03-30T13:28:22Z','level':'ERROR','message':'{"serviceCode": 0, "description": "error message"}','log.source':'analyzer','log.version':1}

cronlogger(version, repo_name, project_name, tags, service)

เป็น class method ที่ log ที่ไว้สำหรับการให้ข้อมูลเพื่อแจ้งขั้นตอนของการทำงานของระบบ ณ ปัจจุบัน โดยใช้กับ script ที่รันในลักษณะ cron job เช่นการ ETL ข้อมูล โดยข้อมูลที่ log สร้างขึ้นจะมีรายละเอียดดังต่อไปนี้

Parameter

name type description
version string เลข version ของ script หรือ repo ซึ่งดึงมาจาก package.json
repo_name string ชื่อของ repo นั้นๆ
project_name string ชื่อของ script ที่รัน ซึ่งดึงมาจาก package.json
tags string ค่า tagging [optional]
service string or dict script นี้เกี่ยวข้องกับ service ไหน [optional]

Output:

Field Name Description
@timestamp เวลาที่ทำการสร้าง log โดยจะอยู่ใน Format %Y-%m-%dT%H:%M:%S
name ชื่อของ repository ที่ใช้งานอยู่ ณ ปัจจุบัน
project ชื่อของ project ที่ repository ที่ใช้งานอยู่ ณ ปัจจุบัน
status สถานะ หรือขั้นตอนการทำงาน ณ ปัจจุบัน ได้แก่ start, running, error และ success
type ประเภทของ log โดยในที่นี้จะเป็น log ประเภท cron
message ข้อความที่ต้องการจะแสดง
tags Tag ที่มีความเกี่ยวข้องกับ project โดยรับค่าเป็น string เช่น 'etl,testing' (optional)
service service ที่มีความเกี่ยวข้องกับโปรเจค (optional)
_version เวอร์ชั่นของ repository

วิธีการเรียกใช้งาน

from thinknet_observer import Logger
# Create instance
cronlog = Logger.cronlogger(version = "1", repo_name= "test", project_name= "testest")
# Generate Log
cronlog.error(message= "test message", extra={"status": "error"})
# {'name': 'test','project': 'testest','status': 'error','type': cron,'tags': ,'service': {},'@timestamp':'2022-03-30T13:28:22Z','message': 'test message','_version':1}

Accesslog


accesslog เป็น log ที่ใช้กับ service เมื่อมีการส่ง request จะส่ง log กลับมา อ่านวิธีการ configuration เพิ่มเติม https://pgjones.gitlab.io/hypercorn/how_to_guides/configuring.html

ตัวอย่างการใช้งาน

from src.thinknet_observer import _create_logger, AccessLogAtoms
from src.thinknet_observer import clear_multiproc_dir

hypercorn.logging._create_logger = _create_logger
hypercorn.logging.AccessLogAtoms = AccessLogAtoms
clear_multiproc_dir()
bind = environ.get("APP_HOST", "0.0.0.0") + ":" + environ.get("APP_PORT", "8080")
loglevel = "info"
accesslog = "-"
access_log_format = '{"remote-addr":"%(h)s","method" : "%(m)s" ,"url" : "%(U)s", "status" : %(s)s , "trace-id" : "%({trace-id}o)s", "res": "%({content-length}o)s" ,"user-agent" : "%(a)s" ,"timestamp" : "%(t)s" ,"response-time" : "%(M)s" , "referrer" : "%(f)s" , "log.source": "http","log.version": "1"}'
workers = int(environ.get("NUM_WORKER", max_workers()))
root_path = "/face-recognition-service"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thinknet-observer-0.4.21.tar.gz (17.1 kB view hashes)

Uploaded Source

Built Distribution

thinknet_observer-0.4.21-py3-none-any.whl (17.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page