Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(603)

Side by Side Diff: gslib/commands/logging.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gslib/commands/lifecycle.py ('k') | gslib/commands/ls.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*-
1 # Copyright 2011 Google Inc. All Rights Reserved. 2 # Copyright 2011 Google Inc. All Rights Reserved.
2 # 3 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 5 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
6 # 7 #
7 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
8 # 9 #
9 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 13 # See the License for the specific language governing permissions and
13 # limitations under the License. 14 # limitations under the License.
15 """Implementation of logging configuration command for buckets."""
16
17 from __future__ import absolute_import
14 18
15 import getopt 19 import getopt
16 import sys 20 import sys
17 import textwrap
18 21
19 from gslib.command import Command 22 from gslib.command import Command
20 from gslib.command import COMMAND_NAME 23 from gslib.cs_api_map import ApiSelector
21 from gslib.command import COMMAND_NAME_ALIASES
22 from gslib.command import FILE_URIS_OK
23 from gslib.command import MAX_ARGS
24 from gslib.command import MIN_ARGS
25 from gslib.command import PROVIDER_URIS_OK
26 from gslib.command import SUPPORTED_SUB_ARGS
27 from gslib.command import URIS_START_ARG
28 from gslib.exception import CommandException 24 from gslib.exception import CommandException
29 from gslib.help_provider import CreateHelpText 25 from gslib.help_provider import CreateHelpText
30 from gslib.help_provider import HELP_NAME 26 from gslib.storage_url import StorageUrlFromString
31 from gslib.help_provider import HELP_NAME_ALIASES 27 from gslib.third_party.storage_apitools import encoding as encoding
32 from gslib.help_provider import HELP_ONE_LINE_SUMMARY 28 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m essages
33 from gslib.help_provider import HELP_TEXT
34 from gslib.help_provider import HelpType
35 from gslib.help_provider import HELP_TYPE
36 from gslib.help_provider import SUBCOMMAND_HELP_TEXT
37 from gslib.util import NO_MAX 29 from gslib.util import NO_MAX
38 from gslib.util import UnaryDictToXml 30 from gslib.util import UrlsAreForSingleProvider
39 from xml.dom.minidom import parseString as XmlParseString
40 31
41 _SET_SYNOPSIS = """ 32 _SET_SYNOPSIS = """
42 gsutil logging set on -b logging_bucket [-o log_object_prefix] uri... 33 gsutil logging set on -b logging_bucket [-o log_object_prefix] url...
43 gsutil logging set off uri... 34 gsutil logging set off url...
44 """ 35 """
45 36
46 _GET_SYNOPSIS = """ 37 _GET_SYNOPSIS = """
47 gsutil logging get uri 38 gsutil logging get url
48 """ 39 """
49 40
50 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n') + '\n' 41 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n') + '\n'
51 42
52 _SET_DESCRIPTION = """ 43 _SET_DESCRIPTION = """
53 <B>SET</B> 44 <B>SET</B>
54 The set sub-command has two sub-commands: 45 The set sub-command has two sub-commands:
55 46
56 <B>ON</B> 47 <B>ON</B>
57 The "gsutil set on" command will enable access logging of the 48 The "gsutil set on" command will enable access logging of the
58 buckets named by the specified uris, outputting log files in the specified 49 buckets named by the specified URLs, outputting log files in the specified
59 logging_bucket. logging_bucket must already exist, and all URIs must name 50 logging_bucket. logging_bucket must already exist, and all URLs must name
60 buckets (e.g., gs://bucket). The required bucket parameter specifies the 51 buckets (e.g., gs://bucket). The required bucket parameter specifies the
61 bucket to which the logs are written, and the optional log_object_prefix 52 bucket to which the logs are written, and the optional log_object_prefix
62 parameter specifies the prefix for log object names. The default prefix 53 parameter specifies the prefix for log object names. The default prefix
63 is the bucket name. For example, the command: 54 is the bucket name. For example, the command:
64 55
65 gsutil logging set on -b gs://my_logging_bucket -o AccessLog \\ 56 gsutil logging set on -b gs://my_logging_bucket -o AccessLog \\
66 gs://my_bucket1 gs://my_bucket2 57 gs://my_bucket1 gs://my_bucket2
67 58
68 will cause all read and write activity to objects in gs://mybucket1 and 59 will cause all read and write activity to objects in gs://mybucket1 and
69 gs://mybucket2 to be logged to objects prefixed with the name "AccessLog", 60 gs://mybucket2 to be logged to objects prefixed with the name "AccessLog",
70 with those log objects written to the bucket gs://my_logging_bucket. 61 with those log objects written to the bucket gs://my_logging_bucket.
71 62
72 Next, you need to grant cloud-storage-analytics@google.com write access to 63 Next, you need to grant cloud-storage-analytics@google.com write access to
73 the log bucket, using this command: 64 the log bucket, using this command:
74 65
75 acl ch -g cloud-storage-analytics@google.com:W gs://my_logging_bucket 66 acl ch -g cloud-storage-analytics@google.com:W gs://my_logging_bucket
76 67
77 Note that log data may contain sensitive information, so you should make 68 Note that log data may contain sensitive information, so you should make
78 sure to set an appropriate default bucket ACL to protect that data. (See 69 sure to set an appropriate default bucket ACL to protect that data. (See
79 "gsutil help defacl".) 70 "gsutil help defacl".)
80 71
81 <B>OFF</B> 72 <B>OFF</B>
82 This command will disable access logging of the buckets named by the 73 This command will disable access logging of the buckets named by the
83 specified uris. All URIs must name buckets (e.g., gs://bucket). 74 specified URLs. All URLs must name buckets (e.g., gs://bucket).
84 75
85 No logging data is removed from the log buckets when you disable logging, 76 No logging data is removed from the log buckets when you disable logging,
86 but Google Cloud Storage will stop delivering new logs once you have 77 but Google Cloud Storage will stop delivering new logs once you have
87 run this command. 78 run this command.
88 79
89 """ 80 """
90 81
91 _GET_DESCRIPTION = """ 82 _GET_DESCRIPTION = """
92 <B>GET</B> 83 <B>GET</B>
93 If logging is enabled for the specified bucket uri, the server responds 84 If logging is enabled for the specified bucket url, the server responds
94 with a <Logging> XML element that looks something like this: 85 with a JSON document that looks something like this:
95 86
96 <?xml version="1.0" ?> 87 {
97 <Logging> 88 "logObjectPrefix": "AccessLog",
98 <LogBucket> 89 "logBucket": "my_logging_bucket"
99 logs-bucket 90 }
100 </LogBucket>
101 <LogObjectPrefix>
102 my-logs-enabled-bucket
103 </LogObjectPrefix>
104 </Logging>
105
106 If logging is not enabled, an empty <Logging> element is returned.
107 91
108 You can download log data from your log bucket using the gsutil cp command. 92 You can download log data from your log bucket using the gsutil cp command.
109 93
110 """ 94 """
111 95
112 _DESCRIPTION = """ 96 _DESCRIPTION = """
113 Google Cloud Storage offers access logs and storage data in the form of 97 Google Cloud Storage offers access logs and storage data in the form of
114 CSV files that you can download and view. Access logs provide information 98 CSV files that you can download and view. Access logs provide information
115 for all of the requests made on a specified bucket in the last 24 hours, 99 for all of the requests made on a specified bucket in the last 24 hours,
116 while the storage logs provide information about the storage consumption of 100 while the storage logs provide information about the storage consumption of
117 that bucket for the last 24 hour period. The logs and storage data files 101 that bucket for the last 24 hour period. The logs and storage data files
118 are automatically created as new objects in a bucket that you specify, in 102 are automatically created as new objects in a bucket that you specify, in
119 24 hour intervals. 103 24 hour intervals.
120 104
121 The logging command has two sub-commands: 105 The logging command has two sub-commands:
122 """ + _SET_DESCRIPTION + _GET_DESCRIPTION + """ 106 """ + _SET_DESCRIPTION + _GET_DESCRIPTION + """
123 107
124 <B>ACCESS LOG AND STORAGE DATA FIELDS</B> 108 <B>ACCESS LOG AND STORAGE DATA FIELDS</B>
125 For a complete list of access log fields and storage data fields, see: 109 For a complete list of access log fields and storage data fields, see:
126 https://developers.google.com/storage/docs/accesslogs#reviewing 110 https://developers.google.com/storage/docs/accesslogs#reviewing
127 """ 111 """
128 112
129 _detailed_help_text = CreateHelpText(_SYNOPSIS, _DESCRIPTION) 113 _DETAILED_HELP_TEXT = CreateHelpText(_SYNOPSIS, _DESCRIPTION)
130 114
131 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION) 115 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION)
132 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION) 116 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION)
133 117
134 118
135 class LoggingCommand(Command): 119 class LoggingCommand(Command):
136 """Implementation of gsutil logging command.""" 120 """Implementation of gsutil logging command."""
137 121
138 # Command specification (processed by parent class). 122 # Command specification. See base class for documentation.
139 command_spec = { 123 command_spec = Command.CreateCommandSpec(
140 # Name of command. 124 'logging',
141 COMMAND_NAME : 'logging', 125 command_name_aliases=['disablelogging', 'enablelogging', 'getlogging'],
142 # List of command name aliases. 126 min_args=2,
143 COMMAND_NAME_ALIASES : ['disablelogging', 'enablelogging', 'getlogging'], 127 max_args=NO_MAX,
144 # Min number of args required by this command. 128 supported_sub_args='b:o:',
145 MIN_ARGS : 2, 129 file_url_ok=False,
146 # Max number of args required by this command, or NO_MAX. 130 provider_url_ok=False,
147 MAX_ARGS : NO_MAX, 131 urls_start_arg=0,
148 # Getopt-style string specifying acceptable sub args. 132 gs_api_support=[ApiSelector.XML, ApiSelector.JSON],
149 SUPPORTED_SUB_ARGS : 'b:o:', 133 gs_default_api=ApiSelector.JSON,
150 # True if file URIs acceptable for this command. 134 )
151 FILE_URIS_OK : False, 135 # Help specification. See help_provider.py for documentation.
152 # True if provider-only URIs acceptable for this command. 136 help_spec = Command.HelpSpec(
153 PROVIDER_URIS_OK : False, 137 help_name='logging',
154 # Index in args of first URI arg. 138 help_name_aliases=['loggingconfig', 'logs', 'log', 'getlogging',
155 URIS_START_ARG : 0,
156 }
157 help_spec = {
158 # Name of command or auxiliary help info for which this help applies.
159 HELP_NAME : 'logging',
160 # List of help name aliases.
161 HELP_NAME_ALIASES : ['loggingconfig', 'logs', 'log', 'getlogging',
162 'enablelogging', 'disablelogging'], 139 'enablelogging', 'disablelogging'],
163 # Type of help: 140 help_type='command_help',
164 HELP_TYPE : HelpType.COMMAND_HELP, 141 help_one_line_summary='Configure or retrieve logging on buckets',
165 # One line summary of this help. 142 help_text=_DETAILED_HELP_TEXT,
166 HELP_ONE_LINE_SUMMARY : 'Configure or retrieve logging on buckets', 143 subcommand_help_text={'get': _get_help_text, 'set': _set_help_text},
167 # The full help text. 144 )
168 HELP_TEXT : _detailed_help_text,
169 # Help text for sub-commands.
170 SUBCOMMAND_HELP_TEXT : {'get' : _get_help_text,
171 'set' : _set_help_text},
172 }
173 145
174 def _Get(self): 146 def _Get(self):
175 uri_args = self.args 147 """Gets logging configuration for a bucket."""
148 bucket_url, bucket_metadata = self.GetSingleBucketUrlFromArg(
149 self.args[0], bucket_fields=['logging'])
176 150
177 # Iterate over URIs, expanding wildcards, and getting the website 151 if bucket_url.scheme == 's3':
178 # configuration on each. 152 sys.stdout.write(self.gsutil_api.XmlPassThroughGetLogging(
179 some_matched = False 153 bucket_url, provider=bucket_url.scheme))
180 for uri_str in uri_args: 154 else:
181 for blr in self.WildcardIterator(uri_str): 155 if (bucket_metadata.logging and bucket_metadata.logging.logBucket and
182 uri = blr.GetUri() 156 bucket_metadata.logging.logObjectPrefix):
183 if not uri.names_bucket(): 157 sys.stdout.write(str(encoding.MessageToJson(
184 raise CommandException('URI %s must name a bucket for the %s command' 158 bucket_metadata.logging)) + '\n')
185 % (uri, self.command_name)) 159 else:
186 some_matched = True 160 sys.stdout.write('%s has no logging configuration.\n' % bucket_url)
187 sys.stderr.write('Getting logging config on %s...\n' % uri) 161 return 0
188 logging_config_xml = UnaryDictToXml(uri.get_logging_config())
189 sys.stdout.write(XmlParseString(logging_config_xml).toprettyxml())
190 if not some_matched:
191 raise CommandException('No URIs matched')
192 162
193 def _Enable(self): 163 def _Enable(self):
164 """Enables logging configuration for a bucket."""
194 # Disallow multi-provider 'logging set on' calls, because the schemas 165 # Disallow multi-provider 'logging set on' calls, because the schemas
195 # differ. 166 # differ.
196 storage_uri = self.UrisAreForSingleProvider(self.args) 167 if not UrlsAreForSingleProvider(self.args):
197 if not storage_uri:
198 raise CommandException('"logging set on" command spanning providers not ' 168 raise CommandException('"logging set on" command spanning providers not '
199 'allowed.') 169 'allowed.')
200 target_bucket_uri = None 170 target_bucket_url = None
201 target_prefix = None 171 target_prefix = None
202 for opt, opt_arg in self.sub_opts: 172 for opt, opt_arg in self.sub_opts:
203 if opt == '-b': 173 if opt == '-b':
204 target_bucket_uri = self.suri_builder.StorageUri(opt_arg) 174 target_bucket_url = StorageUrlFromString(opt_arg)
205 if opt == '-o': 175 if opt == '-o':
206 target_prefix = opt_arg 176 target_prefix = opt_arg
207 177
208 if not target_bucket_uri: 178 if not target_bucket_url:
209 raise CommandException('"logging set on" requires \'-b <log_bucket>\' ' 179 raise CommandException('"logging set on" requires \'-b <log_bucket>\' '
210 'option') 180 'option')
211 if not target_bucket_uri.names_bucket(): 181 if not target_bucket_url.IsBucket():
212 raise CommandException('-b option must specify a bucket uri') 182 raise CommandException('-b option must specify a bucket URL.')
213 183
214 did_some_work = False 184 # Iterate over URLs, expanding wildcards and setting logging on each.
215 for uri_str in self.args: 185 some_matched = False
216 for uri in self.WildcardIterator(uri_str).IterUris(): 186 for url_str in self.args:
217 if uri.names_object(): 187 bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id'])
218 raise CommandException('logging cannot be applied to objects') 188 for blr in bucket_iter:
219 did_some_work = True 189 url = blr.storage_url
220 self.logger.info('Enabling logging on %s...', uri) 190 some_matched = True
221 self.proj_id_handler.FillInProjectHeaderIfNeeded( 191 self.logger.info('Enabling logging on %s...', blr)
222 'enablelogging', storage_uri, self.headers) 192 logging = apitools_messages.Bucket.LoggingValue(
223 uri.enable_logging(target_bucket_uri.bucket_name, target_prefix, False, 193 logBucket=target_bucket_url.bucket_name,
224 self.headers) 194 logObjectPrefix=target_prefix or url.bucket_name)
225 if not did_some_work: 195
226 raise CommandException('No URIs matched') 196 bucket_metadata = apitools_messages.Bucket(logging=logging)
197 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
198 provider=url.scheme, fields=['id'])
199 if not some_matched:
200 raise CommandException('No URLs matched')
201 return 0
227 202
228 def _Disable(self): 203 def _Disable(self):
229 did_some_work = False 204 """Disables logging configuration for a bucket."""
230 for uri_str in self.args: 205 # Iterate over URLs, expanding wildcards, and disabling logging on each.
231 for uri in self.WildcardIterator(uri_str).IterUris(): 206 some_matched = False
232 if uri.names_object(): 207 for url_str in self.args:
233 raise CommandException('logging cannot be applied to objects') 208 bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id'])
234 did_some_work = True 209 for blr in bucket_iter:
235 self.logger.info('Disabling logging on %s...', uri) 210 url = blr.storage_url
236 self.proj_id_handler.FillInProjectHeaderIfNeeded('disablelogging', 211 some_matched = True
237 uri, self.headers) 212 self.logger.info('Disabling logging on %s...', blr)
238 uri.disable_logging(False, self.headers) 213 logging = apitools_messages.Bucket.LoggingValue()
239 if not did_some_work:
240 raise CommandException('No URIs matched')
241 214
242 # Command entry point. 215 bucket_metadata = apitools_messages.Bucket(logging=logging)
216 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
217 provider=url.scheme, fields=['id'])
218 if not some_matched:
219 raise CommandException('No URLs matched')
220 return 0
221
243 def RunCommand(self): 222 def RunCommand(self):
223 """Command entry point for the logging command."""
244 # Parse the subcommand and alias for the new logging command. 224 # Parse the subcommand and alias for the new logging command.
245 action_subcommand = self.args.pop(0) 225 action_subcommand = self.args.pop(0)
246 if action_subcommand == 'get': 226 if action_subcommand == 'get':
247 func = self._Get 227 func = self._Get
248 elif action_subcommand == 'set': 228 elif action_subcommand == 'set':
249 state_subcommand = self.args.pop(0) 229 state_subcommand = self.args.pop(0)
250 if not self.args: 230 if not self.args:
251 self._RaiseWrongNumberOfArgumentsException() 231 self._RaiseWrongNumberOfArgumentsException()
252 if state_subcommand == 'on': 232 if state_subcommand == 'on':
253 func = self._Enable 233 func = self._Enable
254 elif state_subcommand == 'off': 234 elif state_subcommand == 'off':
255 func = self._Disable 235 func = self._Disable
256 else: 236 else:
257 raise CommandException(( 237 raise CommandException((
258 'Invalid subcommand "%s" for the "%s %s" command.\n' 238 'Invalid subcommand "%s" for the "%s %s" command.\n'
259 'See "gsutil help logging".') % 239 'See "gsutil help logging".') % (
260 (state_subcommand, self.command_name, action_subcommand)) 240 state_subcommand, self.command_name, action_subcommand))
261 else: 241 else:
262 raise CommandException(('Invalid subcommand "%s" for the %s command.\n' 242 raise CommandException(('Invalid subcommand "%s" for the %s command.\n'
263 'See "gsutil help logging".') % 243 'See "gsutil help logging".') %
264 (action_subcommand, self.command_name)) 244 (action_subcommand, self.command_name))
265 try: 245 try:
266 (self.sub_opts, self.args) = getopt.getopt(self.args, 246 self.sub_opts, self.args = getopt.getopt(
267 self.command_spec[SUPPORTED_SUB_ARGS]) 247 self.args, self.command_spec.supported_sub_args)
268 self.CheckArguments() 248 self.CheckArguments()
269 except getopt.GetoptError, e: 249 except getopt.GetoptError, e:
270 raise CommandException('%s for "%s" command.' % (e.msg, 250 raise CommandException('%s for "%s" command.' % (e.msg,
271 self.command_name)) 251 self.command_name))
272 func() 252 func()
273 return 0 253 return 0
OLDNEW
« no previous file with comments | « gslib/commands/lifecycle.py ('k') | gslib/commands/ls.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698