diff --git a/synapse/config/logger.py b/synapse/config/logger.py
index b7145a44ae..cbbe221965 100644
--- a/synapse/config/logger.py
+++ b/synapse/config/logger.py
@@ -33,7 +33,6 @@ from twisted.logger import (
globalLogBeginner,
)
-from synapse.logging._structured import setup_structured_logging
from synapse.logging.context import LoggingContextFilter
from synapse.logging.filter import MetadataFilter
@@ -138,6 +137,12 @@ Support for the log_file configuration option and --log-file command-line option
removed in Synapse 1.3.0. You should instead set up a separate log configuration file.
"""
+STRUCTURED_ERROR = """\
+Support for the structured configuration option was removed in Synapse 1.54.0.
+You should instead use the standard logging configuration. See
+https://matrix-org.github.io/synapse/v1.54/structured_logging.html
+"""
+
class LoggingConfig(Config):
section = "logging"
@@ -292,10 +297,9 @@ def _load_logging_config(log_config_path: str) -> None:
if not log_config:
logging.warning("Loaded a blank logging config?")
- # If the old structured logging configuration is being used, convert it to
- # the new style configuration.
+ # If the old structured logging configuration is being used, raise an error.
if "structured" in log_config and log_config.get("structured"):
- log_config = setup_structured_logging(log_config)
+ raise ConfigError(STRUCTURED_ERROR)
logging.config.dictConfig(log_config)
diff --git a/synapse/logging/_structured.py b/synapse/logging/_structured.py
deleted file mode 100644
index b9933a1528..0000000000
--- a/synapse/logging/_structured.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright 2019 The Matrix.org Foundation C.I.C.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import os.path
-from typing import Any, Dict, Generator, Optional, Tuple
-
-from constantly import NamedConstant, Names
-
-from synapse.config._base import ConfigError
-
-
-class DrainType(Names):
- CONSOLE = NamedConstant()
- CONSOLE_JSON = NamedConstant()
- CONSOLE_JSON_TERSE = NamedConstant()
- FILE = NamedConstant()
- FILE_JSON = NamedConstant()
- NETWORK_JSON_TERSE = NamedConstant()
-
-
-DEFAULT_LOGGERS = {"synapse": {"level": "info"}}
-
-
-def parse_drain_configs(
- drains: dict,
-) -> Generator[Tuple[str, Dict[str, Any]], None, None]:
- """
- Parse the drain configurations.
-
- Args:
- drains (dict): A list of drain configurations.
-
- Yields:
- dict instances representing a logging handler.
-
- Raises:
- ConfigError: If any of the drain configuration items are invalid.
- """
-
- for name, config in drains.items():
- if "type" not in config:
- raise ConfigError("Logging drains require a 'type' key.")
-
- try:
- logging_type = DrainType.lookupByName(config["type"].upper())
- except ValueError:
- raise ConfigError(
- "%s is not a known logging drain type." % (config["type"],)
- )
-
- # Either use the default formatter or the tersejson one.
- if logging_type in (
- DrainType.CONSOLE_JSON,
- DrainType.FILE_JSON,
- ):
- formatter: Optional[str] = "json"
- elif logging_type in (
- DrainType.CONSOLE_JSON_TERSE,
- DrainType.NETWORK_JSON_TERSE,
- ):
- formatter = "tersejson"
- else:
- # A formatter of None implies using the default formatter.
- formatter = None
-
- if logging_type in [
- DrainType.CONSOLE,
- DrainType.CONSOLE_JSON,
- DrainType.CONSOLE_JSON_TERSE,
- ]:
- location = config.get("location")
- if location is None or location not in ["stdout", "stderr"]:
- raise ConfigError(
- (
- "The %s drain needs the 'location' key set to "
- "either 'stdout' or 'stderr'."
- )
- % (logging_type,)
- )
-
- yield name, {
- "class": "logging.StreamHandler",
- "formatter": formatter,
- "stream": "ext://sys." + location,
- }
-
- elif logging_type in [DrainType.FILE, DrainType.FILE_JSON]:
- if "location" not in config:
- raise ConfigError(
- "The %s drain needs the 'location' key set." % (logging_type,)
- )
-
- location = config.get("location")
- if os.path.abspath(location) != location:
- raise ConfigError(
- "File paths need to be absolute, '%s' is a relative path"
- % (location,)
- )
-
- yield name, {
- "class": "logging.FileHandler",
- "formatter": formatter,
- "filename": location,
- }
-
- elif logging_type in [DrainType.NETWORK_JSON_TERSE]:
- host = config.get("host")
- port = config.get("port")
- maximum_buffer = config.get("maximum_buffer", 1000)
-
- yield name, {
- "class": "synapse.logging.RemoteHandler",
- "formatter": formatter,
- "host": host,
- "port": port,
- "maximum_buffer": maximum_buffer,
- }
-
- else:
- raise ConfigError(
- "The %s drain type is currently not implemented."
- % (config["type"].upper(),)
- )
-
-
-def setup_structured_logging(
- log_config: dict,
-) -> dict:
- """
- Convert a legacy structured logging configuration (from Synapse < v1.23.0)
- to one compatible with the new standard library handlers.
- """
- if "drains" not in log_config:
- raise ConfigError("The logging configuration requires a list of drains.")
-
- new_config = {
- "version": 1,
- "formatters": {
- "json": {"class": "synapse.logging.JsonFormatter"},
- "tersejson": {"class": "synapse.logging.TerseJsonFormatter"},
- },
- "handlers": {},
- "loggers": log_config.get("loggers", DEFAULT_LOGGERS),
- "root": {"handlers": []},
- }
-
- for handler_name, handler in parse_drain_configs(log_config["drains"]):
- new_config["handlers"][handler_name] = handler
-
- # Add each handler to the root logger.
- new_config["root"]["handlers"].append(handler_name)
-
- return new_config
|