浏览代码

log_driver and log_opt moved to logging key.

Signed-off-by: Dimitar Bonev <[email protected]>
Dimitar Bonev 9 年之前
父节点
当前提交
ed5f7bd394

+ 1 - 2
compose/config/config.py

@@ -51,8 +51,6 @@ DOCKER_CONFIG_KEYS = [
     'ipc',
     'labels',
     'links',
-    'log_driver',
-    'log_opt',
     'mac_address',
     'mem_limit',
     'memswap_limit',
@@ -78,6 +76,7 @@ ALLOWED_KEYS = DOCKER_CONFIG_KEYS + [
     'dockerfile',
     'expose',
     'external_links',
+    'logging',
 ]
 
 DOCKER_VALID_URL_PREFIXES = (

+ 9 - 2
compose/config/fields_schema_v1.json

@@ -75,8 +75,15 @@
         "labels": {"$ref": "#/definitions/list_or_dict"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
-        "log_driver": {"type": "string"},
-        "log_opt": {"type": "object"},
+        "logging": {
+            "type": "object",
+
+            "properties": {
+                "driver": {"type": "string"},
+                "options": {"type": "object"}
+            },
+            "additionalProperties": false
+        },
 
         "mac_address": {"type": "string"},
         "mem_limit": {"type": ["number", "string"]},

+ 21 - 4
compose/service.py

@@ -510,6 +510,13 @@ class Service(object):
 
         return volumes_from
 
+    def get_logging_options(self):
+        logging_dict = self.options.get('logging', {})
+        return {
+            'log_driver': logging_dict.get('driver', ""),
+            'log_opt': logging_dict.get('options', None)
+        }
+
     def _get_container_create_options(
             self,
             override_options,
@@ -523,6 +530,8 @@ class Service(object):
             for k in DOCKER_CONFIG_KEYS if k in self.options)
         container_options.update(override_options)
 
+        container_options.update(self.get_logging_options())
+
         if self.custom_container_name() and not one_off:
             container_options['name'] = self.custom_container_name()
         elif not container_options.get('name'):
@@ -590,10 +599,9 @@ class Service(object):
     def _get_container_host_config(self, override_options, one_off=False):
         options = dict(self.options, **override_options)
 
-        log_config = LogConfig(
-            type=options.get('log_driver', ""),
-            config=options.get('log_opt', None)
-        )
+        logging_dict = options.get('logging', None)
+        log_config = get_log_config(logging_dict)
+
         return self.client.create_host_config(
             links=self._get_links(link_to_self=one_off),
             port_bindings=build_port_bindings(options.get('ports') or []),
@@ -953,3 +961,12 @@ def build_ulimits(ulimit_config):
             ulimits.append(ulimit_dict)
 
     return ulimits
+
+
+def get_log_config(logging_dict):
+    log_driver = logging_dict.get('driver', "") if logging_dict else ""
+    log_options = logging_dict.get('options', None) if logging_dict else None
+    return LogConfig(
+        type=log_driver,
+        config=log_options
+    )

+ 18 - 10
docs/compose-file.md

@@ -324,29 +324,37 @@ for this service, e.g:
 Environment variables will also be created - see the [environment variable
 reference](env.md) for details.
 
-### log_driver
+### logging
 
-Specify a logging driver for the service's containers, as with the ``--log-driver``
-option for docker run ([documented here](https://docs.docker.com/engine/reference/logging/overview/)).
+Logging configuration for the service. This configuration replaces the previous
+`log_driver` and `log_opt` keys.
+
+    logging:
+        driver: log_driver
+        options:
+            syslog-address: "tcp://192.168.0.42:123"
+
+The `driver`  name specifies a logging driver for the service's
+containers, as with the ``--log-driver`` option for docker run
+([documented here](https://docs.docker.com/engine/reference/logging/overview/)).
 
 The default value is json-file.
 
-    log_driver: "json-file"
-    log_driver: "syslog"
-    log_driver: "none"
+    driver: "json-file"
+    driver: "syslog"
+    driver: "none"
 
 > **Note:** Only the `json-file` driver makes the logs available directly from
 > `docker-compose up` and `docker-compose logs`. Using any other driver will not
 > print any logs.
 
-### log_opt
+Specify logging options for the logging driver with the ``options`` key, as with the ``--log-opt`` option for `docker run`.
 
-Specify logging options with `log_opt` for the logging driver, as with the ``--log-opt`` option for `docker run`.
 
 Logging options are key value pairs. An example of `syslog` options:
 
-    log_driver: "syslog"
-    log_opt:
+    driver: "syslog"
+    options:
       syslog-address: "tcp://192.168.0.42:123"
 
 ### net

+ 37 - 0
tests/acceptance/cli_test.py

@@ -716,6 +716,43 @@ class CLITestCase(DockerClientTestCase):
         result = self.dispatch(['start'], returncode=1)
         assert 'No containers to start' in result.stderr
 
+    def test_up_logging(self):
+        self.base_dir = 'tests/fixtures/logging-composefile'
+        self.dispatch(['up', '-d'])
+        simple = self.project.get_service('simple').containers()[0]
+        log_config = simple.get('HostConfig.LogConfig')
+        self.assertTrue(log_config)
+        self.assertEqual(log_config.get('Type'), 'none')
+
+        another = self.project.get_service('another').containers()[0]
+        log_config = another.get('HostConfig.LogConfig')
+        self.assertTrue(log_config)
+        self.assertEqual(log_config.get('Type'), 'json-file')
+        self.assertEqual(log_config.get('Config')['max-size'], '10m')
+
+    def test_up_logging_with_multiple_files(self):
+        self.base_dir = 'tests/fixtures/logging-composefile'
+        config_paths = [
+            'docker-compose.yml',
+            'compose2.yml',
+        ]
+        self._project = get_project(self.base_dir, config_paths)
+        self.dispatch(
+            [
+                '-f', config_paths[0],
+                '-f', config_paths[1],
+                'up', '-d',
+            ],
+            None)
+
+        containers = self.project.containers()
+        self.assertEqual(len(containers), 2)
+
+        another = self.project.get_service('another').containers()[0]
+        log_config = another.get('HostConfig.LogConfig')
+        self.assertTrue(log_config)
+        self.assertEqual(log_config.get('Type'), 'none')
+
     def test_pause_unpause(self):
         self.dispatch(['up', '-d'], None)
         service = self.project.get_service('simple')

+ 3 - 0
tests/fixtures/logging-composefile/compose2.yml

@@ -0,0 +1,3 @@
+another:
+  logging:
+    driver: "none"

+ 12 - 0
tests/fixtures/logging-composefile/docker-compose.yml

@@ -0,0 +1,12 @@
+simple:
+  image: busybox:latest
+  command: top
+  logging:
+    driver: "none"
+another:
+  image: busybox:latest
+  command: top
+  logging:
+    driver: "json-file"
+    options:
+        max-size: "10m"

+ 2 - 2
tests/integration/service_test.py

@@ -888,7 +888,7 @@ class ServiceTest(DockerClientTestCase):
         self.assertNotEqual(one_off_container.name, 'my-web-container')
 
     def test_log_drive_invalid(self):
-        service = self.create_service('web', log_driver='xxx')
+        service = self.create_service('web', logging={'driver': 'xxx'})
         expected_error_msg = "logger: no log driver named 'xxx' is registered"
 
         with self.assertRaisesRegexp(APIError, expected_error_msg):
@@ -902,7 +902,7 @@ class ServiceTest(DockerClientTestCase):
         self.assertFalse(log_config['Config'])
 
     def test_log_drive_none(self):
-        service = self.create_service('web', log_driver='none')
+        service = self.create_service('web', logging={'driver': 'none'})
         log_config = create_and_start_container(service).log_config
 
         self.assertEqual('none', log_config['Type'])

+ 2 - 1
tests/unit/service_test.py

@@ -156,7 +156,8 @@ class ServiceTest(unittest.TestCase):
         self.mock_client.create_host_config.return_value = {}
 
         log_opt = {'syslog-address': 'tcp://192.168.0.42:123'}
-        service = Service(name='foo', image='foo', hostname='name', client=self.mock_client, log_driver='syslog', log_opt=log_opt)
+        logging = {'driver': 'syslog', 'options': log_opt}
+        service = Service(name='foo', image='foo', hostname='name', client=self.mock_client, logging=logging)
         service._get_container_create_options({'some': 'overrides'}, 1)
 
         self.assertTrue(self.mock_client.create_host_config.called)