Skip to content

Commit b484781

Browse files
committed
update azure-storage to 0.33
1 parent 33811df commit b484781

File tree

4 files changed

+92
-78
lines changed

4 files changed

+92
-78
lines changed

README.rst

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ the standard Python logging APIs to Microsoft Azure Storage.
1313
Dependencies
1414
------------
1515

16-
* azure-storage
16+
* azure-storage 0.33 or newer
1717

1818
Installation
1919
------------
@@ -57,7 +57,7 @@ property of a table entity along with some system-defined properties
5757
| XXXXX | XXXXXXXXX | YYYY-MM-DD ... | log message |
5858
+--------------+-----------+----------------+-------------+
5959

60-
* *class* azure_storage_logging.handlers.TableStorageHandler(*account_name=None, account_key=None, protocol='https', table='logs', batch_size=0, extra_properties=None, partition_key_formatter=None, row_key_formatter=None*)
60+
* *class* azure_storage_logging.handlers.TableStorageHandler(*account_name=None, account_key=None, protocol='https', table='logs', batch_size=0, extra_properties=None, partition_key_formatter=None, row_key_formatter=None, is_emulated=False*)
6161

6262
Returns a new instance of the **TableStorageHandler** class.
6363
The instance is initialized with the name and the key of your
@@ -154,7 +154,7 @@ and it pushes log messages to specified Azure storage queue.
154154
You can pop log messages from the queue in other applications
155155
using Azure Storage client libraries.
156156

157-
* *class* azure_storage_logging.handlers.QueueStorageHandler(*account_name=None, account_key=None, protocol='https', queue='logs', message_ttl=None, visibility_timeout=None, base64_encoding=False*)
157+
* *class* azure_storage_logging.handlers.QueueStorageHandler(*account_name=None, account_key=None, protocol='https', queue='logs', message_ttl=None, visibility_timeout=None, base64_encoding=False, is_emulated=False*)
158158

159159
Returns a new instance of the **QueueStorageHandler** class.
160160
The instance is initialized with the name and the key of your
@@ -198,7 +198,7 @@ The **BlobStorageRotatingFileHandler** class is a subclass of
198198
log file rotation and stores the outdated one in Azure blob storage
199199
container when the current file reaches a certain size.
200200

201-
* *class* azure_storage_logging.handlers.BlobStorageRotatingFileHandler(*filename, mode='a', maxBytes=0, encoding=None, delay=False, account_name=None, account_key=None, protocol='https', container='logs', zip_compression=False, max_connections=1, max_retries=5, retry_wait=1.0*)
201+
* *class* azure_storage_logging.handlers.BlobStorageRotatingFileHandler(*filename, mode='a', maxBytes=0, encoding=None, delay=False, account_name=None, account_key=None, protocol='https', container='logs', zip_compression=False, max_connections=1, max_retries=5, retry_wait=1.0*, is_emulated=False)
202202

203203
Returns a new instance of the **BlobStorageRotatingFileHandler**
204204
class. The instance is initialized with the name and the key of your
@@ -265,7 +265,7 @@ The **BlobStorageTimedRotatingFileHandler** class is a subclass of
265265
log file rotation and stores the outdated one to Azure blob storage
266266
container at certain timed intervals.
267267

268-
* *class* azure_storage_logging.handlers.BlobStorageTimedRotatingFileHandler(*filename, when='h', interval=1, encoding=None, delay=False, utc=False, account_name=None, account_key=None, protocol='https', container='logs', zip_compression=False, max_connections=1, max_retries=5, retry_wait=1.0*)
268+
* *class* azure_storage_logging.handlers.BlobStorageTimedRotatingFileHandler(*filename, when='h', interval=1, encoding=None, delay=False, utc=False, account_name=None, account_key=None, protocol='https', container='logs', zip_compression=False, max_connections=1, max_retries=5, retry_wait=1.0*, is_emulated=False)
269269

270270
Returns a new instance of the **BlobStorageTimedRotatingFileHandler**
271271
class. The instance is initialized with the name and the key of your
@@ -410,15 +410,8 @@ three different types of storage from the logger:
410410
Notice
411411
------
412412

413-
* Follow the instructions below if you want to use this package with
414-
Azure storage emulator that is bundled with Microsoft Azure SDK:
415-
416-
* If your application is not going to run on Azure compute
417-
emulator, set ``EMULATED`` environment variable as ``True`` at first.
418-
419-
* specify nothing for the *account_name* and the *account_key*,
420-
and specify ``http`` for the *protocol* at initialization of
421-
the logging handlers.
413+
* Set *is_emulated* to ``True`` at initialization of the logging handlers
414+
if you want to use this package with Azure storage emulator.
422415

423416
License
424417
-------

azure_storage_logging/handlers.py

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from azure.storage.blob import BlockBlobService
2626
from azure.storage.blob.models import ContentSettings
2727
from azure.storage.queue import QueueService
28-
from azure.storage.table import TableService
28+
from azure.storage.table import TableBatch, TableService
2929

3030
_PY3 = sys.version_info[0] == 3
3131

@@ -48,8 +48,12 @@ def __init__(self,
4848
zip_compression=False,
4949
max_connections=1,
5050
max_retries=5,
51-
retry_wait=1.0):
52-
self.service = BlockBlobService(account_name, account_key, protocol)
51+
retry_wait=1.0,
52+
is_emulated=False):
53+
self.service = BlockBlobService(account_name=account_name,
54+
account_key=account_key,
55+
is_emulated=is_emulated,
56+
protocol=protocol)
5357
self.container_created = False
5458
hostname = gethostname()
5559
self.meta = {'hostname': hostname.replace('_', '-'),
@@ -82,7 +86,7 @@ def put_file_into_storage(self, dirName, fileName):
8286
suffix, content_type = '', 'text/plain'
8387
self.service.create_blob_from_path(container_name=self.container,
8488
blob_name=fileName+suffix,
85-
file_path=fileName,
89+
file_path=file_path,
8690
content_settings=ContentSettings(content_type=content_type),
8791
max_connections=self.max_connections
8892
) # max_retries and retry_wait no longer arguments in azure 0.33
@@ -113,7 +117,8 @@ def __init__(self,
113117
zip_compression=False,
114118
max_connections=1,
115119
max_retries=5,
116-
retry_wait=1.0):
120+
retry_wait=1.0,
121+
is_emulated=False):
117122
meta = {'hostname': gethostname(), 'process': os.getpid()}
118123
RotatingFileHandler.__init__(self,
119124
filename % meta,
@@ -123,14 +128,15 @@ def __init__(self,
123128
encoding=encoding,
124129
delay=delay)
125130
_BlobStorageFileHandler.__init__(self,
126-
account_name,
127-
account_key,
128-
protocol,
129-
container,
130-
zip_compression,
131-
max_connections,
132-
max_retries,
133-
retry_wait)
131+
account_name=account_name,
132+
account_key=account_key,
133+
protocol=protocol,
134+
container=container,
135+
zip_compression=zip_compression,
136+
max_connections=max_connections,
137+
max_retries=max_retries,
138+
retry_wait=retry_wait,
139+
is_emulated=is_emulated)
134140

135141
def doRollover(self):
136142
"""
@@ -172,7 +178,8 @@ def __init__(self,
172178
zip_compression=False,
173179
max_connections=1,
174180
max_retries=5,
175-
retry_wait=1.0):
181+
retry_wait=1.0,
182+
is_emulated=False):
176183
meta = {'hostname': gethostname(), 'process': os.getpid()}
177184
TimedRotatingFileHandler.__init__(self,
178185
filename % meta,
@@ -183,14 +190,15 @@ def __init__(self,
183190
delay=delay,
184191
utc=utc)
185192
_BlobStorageFileHandler.__init__(self,
186-
account_name,
187-
account_key,
188-
protocol,
189-
container,
190-
zip_compression,
191-
max_connections,
192-
max_retries,
193-
retry_wait)
193+
account_name=account_name,
194+
account_key=account_key,
195+
protocol=protocol,
196+
container=container,
197+
zip_compression=zip_compression,
198+
max_connections=max_connections,
199+
max_retries=max_retries,
200+
retry_wait=retry_wait,
201+
is_emulated=is_emulated)
194202

195203
def emit(self, record):
196204
"""
@@ -233,13 +241,15 @@ def __init__(self,
233241
message_ttl=None,
234242
visibility_timeout=None,
235243
base64_encoding=False,
244+
is_emulated=False,
236245
):
237246
"""
238247
Initialize the handler.
239248
"""
240249
logging.Handler.__init__(self)
241250
self.service = QueueService(account_name=account_name,
242251
account_key=account_key,
252+
is_emulated=is_emulated,
243253
protocol=protocol)
244254
self.meta = {'hostname': gethostname(), 'process': os.getpid()}
245255
self.queue = _formatName(queue, self.meta)
@@ -272,6 +282,10 @@ def emit(self, record):
272282
def _encode_text(self, text):
273283
if self.base64_encoding:
274284
text = b64encode(text.encode('utf-8')).decode('ascii')
285+
# fallback for the breaking change in azure-storage 0.33
286+
elif sys.version_info < (3,):
287+
if not isinstance(text, unicode):
288+
text = text.decode('utf-8')
275289
return text
276290

277291

@@ -290,13 +304,15 @@ def __init__(self,
290304
extra_properties=None,
291305
partition_key_formatter=None,
292306
row_key_formatter=None,
307+
is_emulated=False,
293308
):
294309
"""
295310
Initialize the handler.
296311
"""
297312
logging.Handler.__init__(self)
298313
self.service = TableService(account_name=account_name,
299314
account_key=account_key,
315+
is_emulated=is_emulated,
300316
protocol=protocol)
301317
self.meta = {'hostname': gethostname(), 'process': os.getpid()}
302318
self.table = _formatName(table, self.meta)
@@ -327,10 +343,10 @@ def __init__(self,
327343
self.extra_property_formatters[extra] = f
328344
self.extra_property_names[extra] = self._getFormatName(extra)
329345
# the storage emulator doesn't support batch operations
330-
if batch_size <= 1 or self.service.use_local_storage:
331-
self.batch = False
346+
if batch_size <= 1 or is_emulated:
347+
self.batch = None
332348
else:
333-
self.batch = True
349+
self.batch = TableBatch()
334350
if batch_size > TableStorageHandler.MAX_BATCH_SIZE:
335351
self.batch_size = TableStorageHandler.MAX_BATCH_SIZE
336352
else:
@@ -369,8 +385,6 @@ def emit(self, record):
369385
try:
370386
if not self.ready:
371387
self.service.create_table(self.table)
372-
if self.batch:
373-
self.service.begin_batch()
374388
self.ready = True
375389
# generate partition key for the entity
376390
record.hostname = self.meta['hostname']
@@ -394,12 +408,13 @@ def emit(self, record):
394408
copy.rowno = self.rowno
395409
row_key = self.row_key_formatter.format(copy)
396410
# add entitiy to the table
397-
self.service.insert_or_replace_entity(self.table,
398-
partition_key,
399-
row_key,
400-
entity)
401-
# commit the ongoing batch if it reaches the high mark
402-
if self.batch:
411+
entity['PartitionKey'] = partition_key
412+
entity['RowKey'] = row_key
413+
if not self.batch:
414+
self.service.insert_or_replace_entity(self.table, entity)
415+
else:
416+
self.batch.insert_or_replace_entity(entity)
417+
# commit the ongoing batch if it reaches the high mark
403418
self.rowno += 1
404419
if self.rowno >= self.batch_size:
405420
self.flush()
@@ -414,10 +429,10 @@ def flush(self):
414429
"""
415430
if self.batch and self.rowno > 0:
416431
try:
417-
self.service.commit_batch()
432+
self.service.commit_batch(self.table, self.batch)
418433
finally:
419434
self.rowno = 0
420-
self.service.begin_batch()
435+
self.batch = TableBatch()
421436

422437
def setFormatter(self, fmt):
423438
"""

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
'Programming Language :: Python :: 3',
1313
'Programming Language :: Python :: 3.3',
1414
'Programming Language :: Python :: 3.4',
15+
'Programming Language :: Python :: 3.5',
1516
'Topic :: System :: Logging',
1617
]
1718

0 commit comments

Comments
 (0)