diff --git a/changelog.d/12008.removal b/changelog.d/12008.removal
new file mode 100644
index 0000000000..57599d9ee9
--- /dev/null
+++ b/changelog.d/12008.removal
@@ -0,0 +1 @@
+Remove support for the legacy structured logging configuration (please see the the [upgrade notes](https://matrix-org.github.io/synapse/develop/upgrade#legacy-structured-logging-configuration-removal) if you are using `structured: true` in the Synapse configuration).
diff --git a/docs/structured_logging.md b/docs/structured_logging.md
index 14db85f587..805c867653 100644
--- a/docs/structured_logging.md
+++ b/docs/structured_logging.md
@@ -81,14 +81,12 @@ remote endpoint at 10.1.2.3:9999.
## Upgrading from legacy structured logging configuration
-Versions of Synapse prior to v1.23.0 included a custom structured logging
-configuration which is deprecated. It used a `structured: true` flag and
-configured `drains` instead of ``handlers`` and `formatters`.
-
-Synapse currently automatically converts the old configuration to the new
-configuration, but this will be removed in a future version of Synapse. The
-following reference can be used to update your configuration. Based on the drain
-`type`, we can pick a new handler:
+Versions of Synapse prior to v1.54.0 automatically converted the legacy
+structured logging configuration, which was deprecated in v1.23.0, to the standard
+library logging configuration.
+
+The following reference can be used to update your configuration. Based on the
+drain `type`, we can pick a new handler:
1. For a type of `console`, `console_json`, or `console_json_terse`: a handler
with a class of `logging.StreamHandler` and a `stream` of `ext://sys.stdout`
diff --git a/docs/upgrade.md b/docs/upgrade.md
index 477d7d0e81..9860ae97b9 100644
--- a/docs/upgrade.md
+++ b/docs/upgrade.md
@@ -85,6 +85,15 @@ process, for example:
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
```
+# Upgrading to v1.54.0
+
+## Legacy structured logging configuration removal
+
+This release removes support for the `structured: true` logging configuration
+which was deprecated in Synapse v1.23.0. If your logging configuration contains
+`structured: true` then it should be modified based on the
+[structured logging documentation](structured_logging.md).
+
# Upgrading to v1.53.0
## Dropping support for `webclient` listeners and non-HTTP(S) `web_client_location`
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
|