Skip to content

Commit

Permalink
Publish python logging events to the Language Client (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney authored Dec 4, 2020
1 parent 8effd96 commit 5626723
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 17 deletions.
4 changes: 2 additions & 2 deletions lib/esbonio/changes/26.fix.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Fix discovery of roles so that roles in Sphinx domains are used and that unimplemented
``docutils`` roles are not surfaced.
**Language Server:** Fix discovery of roles so that roles in Sphinx domains are used and
that unimplemented ``docutils`` roles are not surfaced.
1 change: 1 addition & 0 deletions lib/esbonio/changes/27.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Language Server:** Python log events can now published to Language Clients
31 changes: 16 additions & 15 deletions lib/esbonio/esbonio/__main__.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import argparse
import logging
import pathlib
import sys

import appdirs
import esbonio.lsp as lsp

from esbonio import __version__
from esbonio.lsp.logger import LspHandler

LOG_LEVELS = [logging.ERROR, logging.INFO, logging.DEBUG]


def start_server(verbose):
"""Start the language server."""
def configure_logging(verbose, server):

try:
level = LOG_LEVELS[verbose]
level = LOG_LEVELS[-1]
except IndexError:
level = LOG_LEVELS[-1]

logdir = pathlib.Path(appdirs.user_log_dir("esbonio", "swyddfa"))
if not logdir.exists():
logdir.mkdir(parents=True)
logger = logging.getLogger("esbonio")
logger.setLevel(level)

handler = LspHandler(server)
handler.setLevel(level)

logfile = logdir / "language_server.log"
logging.basicConfig(
level=level,
format="[%(levelname)s][%(name)s]: %(message)s",
filemode="w",
filename=str(logfile),
)
formatter = logging.Formatter("[%(name)s] %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)


def start_server(verbose):
"""Start the language server."""

configure_logging(verbose, lsp.server)
lsp.server.start_io()


Expand Down
34 changes: 34 additions & 0 deletions lib/esbonio/esbonio/lsp/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""This module defines a custom logging handler that publishes log messages to an LSP
client."""

import logging

from pygls.server import LanguageServer
from pygls.types import MessageType

_LOG_LEVELS = {
logging.DEBUG: MessageType.Info,
logging.INFO: MessageType.Info,
logging.WARNING: MessageType.Warning,
logging.ERROR: MessageType.Error,
logging.CRITICAL: MessageType.Error,
}


class LspHandler(logging.Handler):
"""A logging handler that will send log records to an LSP client."""

def __init__(self, server: LanguageServer):
super().__init__()
self.server = server

def emit(self, record: logging.LogRecord) -> None:
"""Sends the record to the client."""

# To avoid infinite recursions, it's simpler to just ignore all log records
# coming from pygls...
if "pygls" in record.name:
return

log = self.format(record)
self.server.show_message_log(log, msg_type=_LOG_LEVELS[record.levelno])

0 comments on commit 5626723

Please sign in to comment.