Plugins¶
The service supports the system of plugins. Plugins must be written in the Python programming language.
Plugin types¶
There are two sorts of plugins:
On event plugin. The plugin is triggered when an event occurs. The plugin should implement a callback function. This function is called on each event of the corresponding type. The set of event types is defined by the service developers.
event type
description
monitoring_event
Event contains monitoring points for sending to a custom monitoring system
sending_event
Event contains handler-generated event data for sending to the third-party source
Monitoring plugin example:
This plugin demonstrates the sending of a request monitoring data to another service. All monitoring plugins must implement the BaseRequestMonitoringPlugin abstract class.
Event sending plugin example:
from abc import abstractmethod from typing import List, Optional, Union from aiohttp import ClientSession from classes.event import Event from classes.schemas.event_raw import RawEvent from crutches_on_wheels.cow.plugins.plugins_meta.base_plugins import BaseEventPlugin from crutches_on_wheels.cow.utils.log import Logger from crutches_on_wheels.cow.web.application import LunaApplication class BaseEventSendingPlugin(BaseEventPlugin): """Base class for event sending.""" # event name for triggering callback eventName = "sending_event" @abstractmethod async def sendEvents( self, events: Union[List[Event], List[RawEvent]], handlerId: str, accountId: str, requestId: str, createEventTime: str, endEventTime: str, logger: Logger, ) -> None: """ Callback that is triggered on every success request to handlers. Args: events: event list handlerId: handler id accountId: account id requestId: request id createEventTime: event creation time endEventTime: event end time logger: logger """ async def handleEvent( self, events: Union[List[Event], List[RawEvent]], handlerId: str, accountId: str, requestId: str, createEventTime: str, endEventTime: str, logger: Logger, ): """ Handle events. Args: events: event list handlerId: handler id accountId: account id requestId: request id createEventTime: event creation time endEventTime: event end time logger: logger """ await self.sendEvents(events, handlerId, accountId, requestId, createEventTime, endEventTime, logger) class EventSendingPlugin(BaseEventSendingPlugin): """Sends events to the third-party source. Only one instance of this class exist during the program execution.""" def __init__(self, app: LunaApplication): super().__init__(app) self.url = "http://127.0.0.1:5020/1/buckets" self.session: Optional[ClientSession] = None self.bucket = "plugin_test_bucket" async def close(self): """Stop plugin. Close all open connections and etc.""" if self.session: await self.session.close() async def initialize(self): """Initialize plugin.""" self.session = ClientSession() async with self.session.post(f"{self.url}?bucket={self.bucket}") as resp: if resp.status not in (201, 409): response = await resp.json() raise RuntimeError(f"failed create bucket, {self.bucket}, response: {response}") async def sendEvents( self, events: Union[List[Event], List[RawEvent]], handlerId: str, accountId: str, requestId: str, createEventTime: str, endEventTime: str, logger: Logger, ) -> None: logger.debug( f"Plugin 'EventsOnFinishExampleClass' get events, request_id: {requestId}, " f"event_create_time: {createEventTime}, event_end_time: {endEventTime}" ) prepareEvents = [] for event in events: if isinstance(event, Event): serializationEvent = event.asDict() else: serializationEvent = event.asHandlerEventDict() prepareEvents.append(serializationEvent) msg = { "handler_id": handlerId, "account_id": accountId, "Luna-Request-Id": requestId, "events": prepareEvents, "event_create_time": createEventTime, "event_end_time": endEventTime, } async with ClientSession() as session: async with session.post(f"{self.url}/{self.bucket}/objects", json=msg) as resp: logger.debug(resp.status) logger.debug(await resp.text())This plugin demonstrates the sending of a handler generates event data to the third-party source. All event sending plugins must implement the BaseEventSendingPlugin abstract class.
Background plugin. This sort of plugin is intended for background work.
The background plugin can implement:
custom route
background monitoring of service resources
collaboration of an event plugin and a background plugin (batching monitoring points)
connection to other data sources (Redis, RabbitMQ) and their data processing
Plugin example:
This plugin demonstrates background work and implements a route. All background plugins must implement the BaseRequestMonitoringPlugin abstract class.
Enable plugin¶
If the user implements a plugin, the file with the plugin should be added to the luna_handlers/plugins directory of the service. The plugin filename should be added to the LUNA_HANDLERS_ACTIVE_PLUGINS configuration setting.
LUNA_HANDLERS_ACTIVE_PLUGINS = [event_sending_plugin_example]
List should contains filenames without extension (.py).