Files
opensearch-pyd/samples/logging/log_collection_sample.py
T
Mark Cohen 0ddbf8cafa Pylint integration updates (#643)
* updated files with docstrings to pass pylint

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* updated samples to prepare for enabling missing-docstring linter; will continue to work on this before committing setup.cfg

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* removed missing-function-docstring from setup.cfg so the linter doesn't fail while work on docstrings continues

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* corrected unnecessary return docstring values

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* fixing failure in 'black' on reformatting

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* updated utils to pass missing-function-docstring tests

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* updated functions with missing docstrings or pylint ignore instructions; added a utility to automatically add these ignore instructions to most functions that should be self-describing; rolled back some automatically generated code mistakenly changed

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* * ignoring opensearchpy for pylint and then added it back to noxfile.py
* fixed some lints; created a feature flag for newer dynamic pylint so now lints can be fixed first in legacy code and then enabled by multiple people
* extracted a method for per-folder linting
* updated noxfile.lint_per_folder with type hints
* enabled unspecified-encoding in pylint
* added disable missing-function-docstring pragma to test_clients.py in test_async and test_server
* added more encodings to pass unspecified-encoding pylint tests
* updated changelog
Signed-off-by: Mark Cohen <markcoh@amazon.com>

* updated CHANGELOG.md entry
removed the feature flag for pylint lint_per_folder
fixed failures from mypy and pylint
removed pylint MESSAGE CONTROL config from setup.cfg after relocating to lint_per_folder method
Signed-off-by: Mark Cohen <markcoh@amazon.com>

* removed pylint ignore missing-function-docstring

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* added pylint.extensions.docparams plugin

updated some docstrings to correct parameters

removed pylint from setup.cfg

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* added four lints for opensearchpy/

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* adding await back to client.info() call

Signed-off-by: Mark Cohen <markcoh@amazon.com>

* updated TODOs as requested

renamed test_opensearchpy.test_async.test_server.test_helpers.conftest.setup_ubq_tests to setup_update_by_query_tests

added
OpenSearch-main/rest-api-spec/src/main/resources/rest-api-spec/test/indices/stats/50_noop_update[0]
to skip tests list

run_tests.py catches a CalledProcessError when the git repo already exists and the command to add the origin fails in fetch_opensearch_repo()

Signed-off-by: Mark Cohen <markcoh@amazon.com>

---------

Signed-off-by: Mark Cohen <markcoh@amazon.com>
2024-01-19 13:36:05 -05:00

128 lines
4.2 KiB
Python

#!/usr/bin/env python
# SPDX-License-Identifier: Apache-2.0
#
# The OpenSearch Contributors require contributions made to
# this file be licensed under the Apache-2.0 license or a
# compatible open source license.
#
# Modifications Copyright OpenSearch Contributors. See
# GitHub history for details.
import logging
import queue
from datetime import datetime
from logging.handlers import QueueHandler, QueueListener
from typing import Any
import urllib3
from opensearchpy import OpenSearch
urllib3.disable_warnings()
def main() -> None:
"""
sample for custom logging; this shows how to create a
console handler, connect to OpenSearch, define a custom
logger, and log to an OpenSearch index
"""
print("Collecting logs.")
# Create a console handler
console_handler: logging.StreamHandler = logging.StreamHandler() # type: ignore
console_handler.setLevel(logging.INFO)
# Setup connection with the OpenSearch cluster
print("Setting up connection with OpenSearch cluster...")
opensearch_client: Any = OpenSearch(
"https://admin:admin@localhost:9200",
use_ssl=True,
verify_certs=False,
ssl_show_warn=False,
http_auth=("admin", "admin"),
)
# Initialize a logger named "OpenSearchLogs" for OpenSearch
print("Initializing logger...")
os_logger: logging.Logger = logging.getLogger("OpenSearchLogs")
os_logger.setLevel(logging.INFO)
# Add console handler to the logger
os_logger.addHandler(console_handler)
class OpenSearchHandler(logging.Handler):
"""
define a custom handler that logs to opensearch
"""
# Initializer / Instance attributes
def __init__(self, opensearch_client: Any) -> None:
super().__init__()
self.os_client = opensearch_client
def _build_index_name(self) -> str:
"""
Build index name (e.g., "logs-YYYY-MM-DD")
:rtype: bool
:return: a str with date formatted as 'logs-YYYY-MM-DD'
"""
return f"logs-{datetime.date(datetime.now())}"
# Emit logs to the OpenSearch cluster
def emit(self, record: logging.LogRecord) -> None:
document = {
"timestamp": datetime.fromtimestamp(record.created).isoformat(),
"name": record.name,
"level": record.levelname,
"message": record.getMessage(),
"source": {
"file": record.pathname,
"line": record.lineno,
"function": record.funcName,
},
"process": {"id": record.process, "name": record.processName},
"thread": {"id": record.thread, "name": record.threadName},
}
try:
self.os_client.index(
index=self._build_index_name(),
body=document,
)
except Exception as ex:
print(f"Failed to send log to OpenSearch: {ex}")
logging.warning(f"Failed to send log to OpenSearch: {ex}")
raise
print("Creating an instance of OpenSearchHandler and adding it to the logger...")
# Create an instance of OpenSearchHandler and add it to the logger
os_handler: OpenSearchHandler = OpenSearchHandler(opensearch_client)
os_logger.addHandler(os_handler)
print("Setting up asynchronous logging using Queues...")
# Setup asynchronous logging using Queues
log_queue: queue.Queue[logging.LogRecord] = queue.Queue(-1) # no limit on size
os_queue_handler: logging.Handler = QueueHandler(log_queue)
os_queue_listener: QueueListener = QueueListener(log_queue, os_handler)
# Add queue handler to the logger
os_logger.addHandler(os_queue_handler)
# Start listening on the queue using the os_queue_listener
os_queue_listener.start()
print("Logger is set up and listener has started. Sending a test log...")
# Logging a test message
os_logger.info("This is a test log message")
print("Cleaning up...")
# Stop listening on the queue
os_queue_listener.stop()
print("Log Collection Guide has completed running")
if __name__ == "__main__":
main()