From 58bade66699d015fe0952ff8bc48949e3397b3e6 Mon Sep 17 00:00:00 2001 From: =Zachary Merritt <=zsmerritt@gmail.com> Date: Sat, 31 Jul 2021 02:46:24 -0700 Subject: [PATCH] release 0.2.0 --- CHANGELOG.md | 25 ++- README.md | 141 +++++++++++++---- example/aws_cloudwatch.dart | 40 +++++ example/pubspec.yaml | 2 +- lib/aws_cloudwatch.dart | 302 +++++++++++++++++++++++------------- pubspec.lock | 2 +- pubspec.yaml | 4 +- 7 files changed, 365 insertions(+), 151 deletions(-) create mode 100644 example/aws_cloudwatch.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef5e3e..84fd89c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [0.2.0] - 2021/07/14 + +* Added CloudWatchHandler class to easily manage multiple CloudWatch instances +* Added quick start logging example file +* Automatically creates Log Groups that don't exist +* Updated the README with info on CloudWatchHandler and quick start +* Improved code readability +* Updated to new version of aws_request +* Added min 0 delay in place it was missing + ## [0.1.12] - 2021/07/14 * Fixed bug where delay was input in seconds instead of milliseconds @@ -6,7 +16,7 @@ QOL update -* Fully removed optional deprecated xAmzTarget argument from main constructor (deprecated in 0.1.0) +* Fully removed optional deprecated xAmzTarget argument from main constructor (deprecated in 0.1.0) * Added optional arguments for group / stream name to both constructors * Added missing method setLoggingParameters that was shown in error message when group / stream name was null * Updated all examples to show different group / stream name instantiations @@ -32,13 +42,13 @@ QOL update ## [0.1.7] - 2021/05/18 * Moved to new version of aws_requests to fix hard coded region bug -* Improved error handling - +* Improved error handling + ## [0.1.6] - 2021/03/26 * Added console output logging with 4 verbosity levels * Added optional delay parameter to address possible rate limiting - * Updated readme with new rate limiting example + * Updated readme with new rate limiting example ## [0.1.5] - 2021/03/26 @@ -64,25 +74,28 @@ QOL update * Updated dependencies for null safety * Put deprecation warning on xAmzTarget (formerly serviceInstance - * Updated example and docs to reflect changes with xAmzTarget + * Updated example and docs to reflect changes with xAmzTarget * Added exception if PutLogEvents returns a status code other than 200 ## [0.0.6] - 2021/03/26 Non-null Safety Update + * Updated examples * Fixed issue with attempted logging before logstream creation was finished ## [0.0.5] - 2021/03/25 Non-null Safety Update + * Fixed issue with sending empty logs ## [0.0.4] - 2021/03/25 Non-null Safety Update + * Put deprecation warning on xAmzTarget (formerly serviceInstance) - * Updated example and docs to reflect changes with xAmzTarget + * Updated example and docs to reflect changes with xAmzTarget * Added exception if PutLogEvents returns a status code other than 200 * Updated aws_request version to fix unicode error diff --git a/README.md b/README.md index 40bbbc0..c84b312 100644 --- a/README.md +++ b/README.md @@ -25,36 +25,59 @@ CloudWatch cloudWatch = new CloudWatch(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, Finally, send a log by calling `cloudWatch.log('STRING TO LOG');` -## Important Notes: - -### Avoiding AWS Cloudwatch API Rate Limiting - -As of now (2021/07/09), AWS has a rate limit of 5 log requests per second per log stream. You may hit this limit rather -quickly if you have a high volume of logs. It is highly recommended to include the optional delay parameter with a value -of 200 (milliseconds) to avoid hitting this upper limit. With a delay, logs will continue to collect, but the api calls -will be limited to 5 per second. At the moment there is no way around this limit. - -Example 2 below shows how to add a delay. The default delay is 0 milliseconds. - -### Log Groups and Log Streams +## Examples -Creating streams and uploading logs is the primary reason this package exists. Log groups must still be created -manually. If you would like this feature let me know, and I will work on implementing it. With my use cases, I haven't -felt the need for it. +### Example - Quick Start -There are multiple ways to set the log group and log stream and all are roughly equivalent. +This is the quick start file. It is also location in example/aws_cloudwatch.dart -Log stream names currently (2021/07/09) have the following limits: - -* Log stream names must be unique within the log group. -* Log stream names can be between 1 and 512 characters long. -* The ':' (colon) and '*' (asterisk) characters are not allowed. +~~~dart +import 'package:aws_cloudwatch/aws_cloudwatch.dart'; +import 'package:intl/intl.dart'; + +/// QUICK START LOGGING FILE +/// +/// PLEASE FILL OUT THE FOLLOWING VARIABLES: + +const String _AWS_ACCESS_KEY_ID = 'YOUR_ACCESS_KEY'; +const String _AWS_SECRET_ACCESS_KEY = 'YOUR_SECRET_ACCESS_KEY'; +const String _Region = 'YOUR_REGION_CODE'; // (us-west-1, us-east-2, etc) +const String _LogGroup = 'DESIRED_LOG_GROUP_NAME'; +const String _ErrorGroup = 'DESIRED_ERROR_LOG_GROUP_NAME'; + +/// END OF VARIABLES + +CloudWatchHandler logging = CloudWatchHandler( + awsAccessKey: _AWS_ACCESS_KEY_ID, + awsSecretKey: _AWS_SECRET_ACCESS_KEY, + region: _Region, +); + +String logStreamName = ''; + +// You may want to edit this function to suit your needs +String _getLogStreamName() { + if (logStreamName == "") { + logStreamName = DateFormat("yyyy-MM-dd HH-mm-ss").format( + DateTime.now().toUtc(), + ); + } + return logStreamName; +} -This package does not enforce or check log stream names with regard to these limits in case AWS decides to add or remove -limitations. It is up to **you** to check the errors returned by the API to figure out if the problem is with the -provided log stream name. +void log(String logString, {isError = false}) { + logging.log( + msg: logString, + logGroupName: isError ? _LogGroup : _ErrorGroup, + logStreamName: _getLogStreamName(), + ); +} +~~~ -## Examples +Then just import this file somewhere in your code and call `log('HELLO WORLD');`. The package will handle creating the +log groups and log streams on its own. The way the quick start file is setup, you will end up with one log group for +standard logging and another for errors. Both with have the same log stream name. To automatically send logs for all +flutter errors see example 3. ### Example 1 @@ -115,6 +138,7 @@ it `errorLog.dart` ~~~dart import 'package:aws_request/aws_cloudwatch.dart'; +import 'package:intl/intl.dart'; // AWS Variables const String AWS_ACCESS_KEY_ID = 'ExampleKey'; @@ -123,14 +147,40 @@ const String Region = 'us-west-2'; // Logging Variables const String logGroupName = 'LogGroupExample'; -const String logStreamName = 'LogStreamExample'; -CloudWatch cloudWatch = new CloudWatch(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, - Region); -cloudWatch.setLoggingParameters(logGroupName, logStreamName); +const String logGroupNameError = 'LogGroupExample'; + +CloudWatchHandler logging = CloudWatchHandler( + awsAccessKey: AWS_ACCESS_KEY_ID, + awsSecretKey: AWS_SECRET_ACCESS_KEY, + region: Region, +); + +String logStreamName = ''; + +// You may want to edit this function to suit your needs +String _getLogStreamName() { + if (logStreamName == "") { + logStreamName = DateFormat("yyyy-MM-dd HH-mm-ss").format( + DateTime.now().toUtc(), + ); + } + return logStreamName; +} + +void log(String logString, {isError = false}) { + logging.log( + msg: logString, + logGroupName: isError ? logGroupName : logGroupNameError, + logStreamName: _getLogStreamName(), + ); +} void logFlutterSystemError(dynamic logString, dynamic stackTrace) async { - cloudWatch.log('Auto Captured Error: ${logString.toString()}\n\n' - 'Auto Captured Stack Trace:\n${stackTrace.toString()}'); + log( + 'Auto Captured Error: ${logString.toString()}\n\n' + 'Auto Captured Stack Trace:\n${stackTrace.toString()}', + isError: true, + ); } ~~~ @@ -157,4 +207,31 @@ void main() { throw error; }); } -~~~ \ No newline at end of file +~~~ + +To send normal logs, import the logging file anywhere and call `log('Hello world!');` + +## Important Notes: + +### Avoiding AWS Cloudwatch API Rate Limiting + +As of now (2021/07/09), AWS has a rate limit of 5 log requests per second per log stream. You may hit this limit rather +quickly if you have a high volume of logs. It is highly recommended to include the optional delay parameter with a value +of 200 (milliseconds) to avoid hitting this upper limit. With a delay, logs will continue to collect, but the api calls +will be limited to 5 per second. At the moment there is no way around this limit. + +Example 2 below shows how to add a delay. The default delay is 0 milliseconds. + +### Log Groups and Log Streams + +There are multiple ways to set the log group and log stream and all are roughly equivalent. + +Log stream names currently (2021/07/09) have the following limits: + +* Log stream names must be unique within the log group. +* Log stream names can be between 1 and 512 characters long. +* The ':' (colon) and '*' (asterisk) characters are not allowed. + +This package does not enforce or check log stream names with regard to these limits in case AWS decides to add or remove +limitations. It is up to **you** to check the errors returned by the API to figure out if the problem is with the +provided log stream name. \ No newline at end of file diff --git a/example/aws_cloudwatch.dart b/example/aws_cloudwatch.dart new file mode 100644 index 0000000..1bbac00 --- /dev/null +++ b/example/aws_cloudwatch.dart @@ -0,0 +1,40 @@ +import 'package:aws_cloudwatch/aws_cloudwatch.dart'; +import 'package:intl/intl.dart'; + +/// QUICK START LOGGING FILE +/// +/// PLEASE FILL OUT THE FOLLOWING VARIABLES: + +const String _AWS_ACCESS_KEY_ID = 'YOUR_ACCESS_KEY'; +const String _AWS_SECRET_ACCESS_KEY = 'YOUR_SECRET_ACCESS_KEY'; +const String _Region = 'YOUR_REGION_CODE'; // (us-west-1, us-east-2, etc) +const String _LogGroup = 'DESIRED_LOG_GROUP_NAME'; +const String _ErrorGroup = 'DESIRED_ERROR_LOG_GROUP_NAME'; + +/// END OF VARIABLES + +CloudWatchHandler logging = CloudWatchHandler( + awsAccessKey: _AWS_ACCESS_KEY_ID, + awsSecretKey: _AWS_SECRET_ACCESS_KEY, + region: _Region, +); + +String logStreamName = ''; + +// You may want to edit this function to suit your needs +String _getLogStreamName() { + if (logStreamName == "") { + logStreamName = DateFormat("yyyy-MM-dd HH-mm-ss").format( + DateTime.now().toUtc(), + ); + } + return logStreamName; +} + +void log(String logString, {isError = false}) { + logging.log( + msg: logString, + logGroupName: isError ? _LogGroup : _ErrorGroup, + logStreamName: _getLogStreamName(), + ); +} diff --git a/example/pubspec.yaml b/example/pubspec.yaml index c9616fd..6293c7f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: An AWS CloudWatch wrapper package for easy Flutter cloud logging. Currently only logging is supported. -version: 0.1.10 +version: 0.2.0 homepage: https://github.com/Zsmerritt/Flutter_AWS_CloudWatch environment: diff --git a/lib/aws_cloudwatch.dart b/lib/aws_cloudwatch.dart index ebf0542..113c0d8 100644 --- a/lib/aws_cloudwatch.dart +++ b/lib/aws_cloudwatch.dart @@ -11,22 +11,97 @@ class CloudWatchException implements Exception { String message; String cause; - /// deprecated + /// A custom error to identify CloudWatch errors more easily + /// + /// message: the cause of the error CloudWatchException(String message) : this.cause = message, this.message = message; } +/// A CloudWatch handler class to easily manage multiple CloudWatch instances +class CloudWatchHandler { + Map _logInstances = {}; + String awsAccessKey; + String awsSecretKey; + String region; + int delay; + + /// CloudWatchHandler Constructor + /// + /// awsAccessKey: Your AWS Access key. + /// awsSecretKey: Your AWS Secret key. + /// region: Your AWS region. + /// {delay}: Optional delay parameter to avoid rate limiting (suggested value is 200(ms)) + CloudWatchHandler({ + required this.awsAccessKey, + required this.awsSecretKey, + required this.region, + this.delay: 0, + }); + + /// Returns a specific instance of a CloudWatch class (or null if it doesnt + /// exist) based on group name and stream name + /// + /// logGroupName: the log group name of the instance you would like + /// logStreamName: the stream name of the instance you would like + CloudWatch? getInstance({ + required String logGroupName, + required String logStreamName, + }) { + String instanceName = '$logGroupName.$logStreamName'; + return _logInstances[instanceName]; + } + + /// Logs the provided message to the provided log group and log stream + /// Creates a new CloudWatch instance if needed + /// + /// msg: the message you would like to log + /// logGroupName: the log group the log stream will appear under + /// logStreamName: the name of the logging session + void log({ + required String msg, + required String logGroupName, + required String logStreamName, + }) { + CloudWatch instance = getInstance( + logGroupName: logGroupName, + logStreamName: logStreamName, + ) ?? + _createInstance( + logGroupName: logGroupName, + logStreamName: logStreamName, + ); + instance.log(msg); + } + + CloudWatch _createInstance({ + required String logGroupName, + required String logStreamName, + }) { + String instanceName = '$logGroupName.$logStreamName'; + CloudWatch instance = CloudWatch( + awsAccessKey, + awsSecretKey, + region, + logGroupName: logGroupName, + logStreamName: logStreamName, + delay: delay, + ); + _logInstances[instanceName] = instance; + return instance; + } +} + /// An AWS CloudWatch class for sending logs more easily to AWS class CloudWatch { // AWS Variables - late String _awsAccessKey; - late String _awsSecretKey; - late String _region; - late int _delay; + String awsAccessKey; + String awsSecretKey; + String region; + int delay; int _verbosity = 0; - - AwsRequest? _awsRequest; + late AwsRequest _awsRequest; // Logging Variables /// The log group name for the log stream to go in @@ -39,56 +114,56 @@ class CloudWatch { List> _logStack = []; var _loggingLock = Lock(); bool _logStreamCreated = false; + bool _logGroupCreated = false; /// CloudWatch Constructor + /// /// awsAccessKey: Public AWS access key /// awsSecretKey: Private AWS access key /// region: AWS region - /// {groupName}: The log group the log stream will appear under - /// {streamName}: The name of this logging session + /// {logGroupName}: The log group the log stream will appear under + /// {logStreamName}: The name of this logging session /// {delay}: Milliseconds to wait for more logs to accumulate to avoid rate limiting. - CloudWatch(String awsAccessKey, String awsSecretKey, String region, - {groupName, streamName, delay = 0}) { - logGroupName = groupName; - logStreamName = streamName; - _awsAccessKey = awsAccessKey; - _awsSecretKey = awsSecretKey; - _region = region; - _delay = max(0, delay); + CloudWatch( + this.awsAccessKey, + this.awsSecretKey, + this.region, { + this.logGroupName, + this.logStreamName, + this.delay: 0, + }) { + delay = max(0, delay); + _awsRequest = + AwsRequest(awsAccessKey, awsSecretKey, region, service: 'logs'); } - /// CloudWatch Constructor - /// awsAccessKey: Public AWS access key - /// awsSecretKey: Private AWS access key - /// region: AWS region - /// delay: Milliseconds to wait for more logs to accumulate to avoid rate limiting. - /// {groupName}: The log group the log stream will appear under - /// {streamName}: The name of this logging session + ///DEPRECATED CloudWatch.withDelay( - String awsAccessKey, String awsSecretKey, String region, int delay, - {groupName, streamName}) { - logGroupName = groupName; - logStreamName = streamName; - _awsAccessKey = awsAccessKey; - _awsSecretKey = awsSecretKey; - _region = region; - _delay = max(0, delay); + this.awsAccessKey, + this.awsSecretKey, + this.region, + this.delay, { + this.logGroupName, + this.logStreamName, + }) { + delay = max(0, delay); + _awsRequest = + AwsRequest(awsAccessKey, awsSecretKey, region, service: 'logs'); print('CloudWatch.withDelay is deprecated. Instead call the default ' 'constructor and provide a value for the optional delay parameter'); } - /// Delays sending logs /// Delays sending logs to allow more logs to accumulate to avoid rate limiting + /// /// delay: The amount of milliseconds to wait. int setDelay(int delay) { - _delay = max(0, delay); - if (_verbosity > 2) { - print('CloudWatch INFO: Set delay to $_delay'); - } - return _delay; + delay = max(0, delay); + _debugPrint(2, 'CloudWatch INFO: Set delay to $delay'); + return delay; } /// Sets log group name and log stream name + /// /// groupName: The log group you wish the log to appear under /// streamName: The name for this logging session void setLoggingParameters(String? groupName, String? streamName) { @@ -97,34 +172,33 @@ class CloudWatch { } /// Sets console verbosity level. Default is 0. + /// /// 0 - No console logging. /// 1 - Error console logging. /// 2 - API response logging. /// 3 - Verbose logging + /// /// level: The verbosity level. Valid values are 0 through 3 void setVerbosity(int level) { - level = level > 3 ? 3 : level; - level = level < 0 ? 0 : level; + level = min(level, 3); + level = max(level, 0); _verbosity = level; - if (_verbosity > 2) { - print('CloudWatch INFO: Set verbosity to $_verbosity'); - } + _debugPrint(2, 'CloudWatch INFO: Set verbosity to $_verbosity'); } /// Performs a PutLogEvent to CloudWatch + /// /// logString: the string you want to log in CloudWatch /// /// Throws CloudWatchException if logGroupName or logStreamName are not /// initialized or if aws returns an error. Future log(String logString) async { - if (_verbosity > 2) { - print('CloudWatch INFO: Attempting to log $logString'); - } - if (logGroupName == null || logStreamName == null) { - if (_verbosity > 0) { - print('CloudWatch ERROR: Please supply a Log Group and Stream names by ' - 'calling setLoggingParameters(String? logGroupName, String? logStreamName)'); - } + _debugPrint(2, 'CloudWatch INFO: Attempting to log $logString'); + if ([logGroupName, logStreamName].contains(null)) { + _debugPrint( + 0, + 'CloudWatch ERROR: Please supply a Log Group and Stream names by ' + 'calling setLoggingParameters(String? logGroupName, String? logStreamName)'); throw new CloudWatchException( 'CloudWatch ERROR: Please supply a Log Group and Stream names by ' 'calling setLoggingParameters(String logGroupName, String logStreamName)'); @@ -132,60 +206,84 @@ class CloudWatch { await _log(logString); } - // gets AwsRequest instance and instantiates if needed - AwsRequest? _getAwsRequest() { - if (_awsRequest == null) { - if (_verbosity > 2) { - print('CloudWatch INFO: Generating AwsRequest'); - } - _awsRequest = new AwsRequest(_awsAccessKey, _awsSecretKey, _region); - _awsRequest!.service = 'logs'; + void _debugPrint(int v, String msg) { + if (_verbosity > v) { + print(msg); } - if (_verbosity > 2) { - print('CloudWatch INFO: Got AwsRequest'); + } + + Future _createLogStreamAndLogGroup() async { + try { + await _createLogStream(); + } on CloudWatchException catch (e) { + if (e.message == 'CloudWatch ERROR: ResourceNotFoundException') { + // Create a new log group and try stream creation again + await _createLogGroup(); + await _createLogStream(); + } } - return _awsRequest; } Future _createLogStream() async { if (!_logStreamCreated) { - if (_verbosity > 2) { - print('CloudWatch INFO: Generating LogStream'); - } + _debugPrint(2, 'CloudWatch INFO: Generating LogStream'); _logStreamCreated = true; - AwsRequest request = _getAwsRequest()!; String body = '{"logGroupName": "$logGroupName","logStreamName": "$logStreamName"}'; - HttpClientResponse log = await request.send( + HttpClientResponse log = await _awsRequest.send( 'POST', jsonBody: body, target: 'Logs_20140328.CreateLogStream', ); int statusCode = log.statusCode; - - if (_verbosity > 1) { - print('CloudWatch Info: LogStream creation status code: $statusCode'); - } + _debugPrint( + 1, 'CloudWatch Info: LogStream creation status code: $statusCode'); if (statusCode != 200) { Map? reply = jsonDecode(await log.transform(utf8.decoder).join()); - if (_verbosity > 0) { - print( + if (reply?['__type'] == 'ResourceNotFoundException') { + _logStreamCreated = false; + throw new CloudWatchException( + 'CloudWatch ERROR: ResourceNotFoundException'); + } else { + _debugPrint(0, 'CloudWatch ERROR: StatusCode: $statusCode, CloudWatchResponse: $reply'); + _logStreamCreated = false; + throw new CloudWatchException('CloudWatch ERROR: $reply'); } - throw new CloudWatchException('CloudWatch ERROR: $reply'); } } - if (_verbosity > 2) { - print('CloudWatch INFO: Got LogStream'); + _debugPrint(2, 'CloudWatch INFO: Got LogStream'); + } + + Future _createLogGroup() async { + if (!_logGroupCreated) { + _debugPrint(2, 'CloudWatch INFO: creating LogGroup Exists'); + _logGroupCreated = true; + String body = '{"logGroupName": "$logGroupName"}'; + HttpClientResponse log = await _awsRequest.send( + 'POST', + jsonBody: body, + target: 'Logs_20140328.CreateLogGroup', + ); + int statusCode = log.statusCode; + _debugPrint( + 1, 'CloudWatch Info: LogGroup creation status code: $statusCode'); + if (statusCode != 200) { + Map? reply = + jsonDecode(await log.transform(utf8.decoder).join()); + _debugPrint(0, + 'CloudWatch ERROR: StatusCode: $statusCode, CloudWatchResponse: $reply'); + _logGroupCreated = false; + throw new CloudWatchException('CloudWatch ERROR: $reply'); + } } + _debugPrint(2, 'CloudWatch INFO: created LogGroup'); } // turns a string into a cloudwatch event Future _createBody() async { - if (_verbosity > 2) { - print('CloudWatch INFO: Generating CloudWatch request body'); - } + _debugPrint(2, 'CloudWatch INFO: Generating CloudWatch request body'); Map body = { 'logEvents': _logStack, 'logGroupName': logGroupName, @@ -193,17 +291,13 @@ class CloudWatch { }; if (_sequenceToken != null) { body['sequenceToken'] = _sequenceToken; - if (_verbosity > 2) { - print('CloudWatch INFO: Adding sequence token'); - } + _debugPrint(2, 'CloudWatch INFO: Adding sequence token'); } int logLength = _logStack.length; String jsonBody = json.encode(body); _logStack = []; - if (_verbosity > 2) { - print( - 'CloudWatch INFO: Generated jsonBody with $logLength logs: $jsonBody'); - } + _debugPrint(2, + 'CloudWatch INFO: Generated jsonBody with $logLength logs: $jsonBody'); return jsonBody; } @@ -211,15 +305,13 @@ class CloudWatch { int time = DateTime.now().toUtc().millisecondsSinceEpoch; Map message = {'timestamp': time, 'message': logString}; _logStack.add(message); - if (_verbosity > 2) { - print('CloudWatch INFO: Added message to log stack: $message'); - } - if (!_logStreamCreated) { - await _loggingLock.synchronized(_createLogStream).catchError((e) { - return Future.error(CloudWatchException(e.message)); - }); - } - sleep(new Duration(milliseconds: _delay)); + _debugPrint(2, 'CloudWatch INFO: Added message to log stack: $message'); + await _loggingLock + .synchronized(_createLogStreamAndLogGroup) + .catchError((e) { + return Future.error(CloudWatchException(e.message)); + }); + sleep(new Duration(seconds: delay)); await _loggingLock.synchronized(_sendLogs).catchError((e) { return Future.error(CloudWatchException(e.message)); }); @@ -228,14 +320,11 @@ class CloudWatch { Future _sendLogs() async { if (_logStack.length <= 0) { // logs already sent while this request was waiting for lock - if (_verbosity > 2) { - print('CloudWatch INFO: All logs have already been sent'); - } + _debugPrint(2, 'CloudWatch INFO: All logs have already been sent'); return; } - AwsRequest request = _getAwsRequest()!; String body = await _createBody(); - HttpClientResponse result = await request.send( + HttpClientResponse result = await _awsRequest.send( 'POST', jsonBody: body, target: 'Logs_20140328.PutLogEvents', @@ -243,19 +332,14 @@ class CloudWatch { int statusCode = result.statusCode; Map? reply = jsonDecode(await result.transform(utf8.decoder).join()); - - if (_verbosity > 1) { - print( - 'CloudWatch Info: StatusCode: $statusCode, CloudWatchResponse: $reply'); - } if (statusCode == 200) { + _debugPrint(1, + 'CloudWatch Info: StatusCode: $statusCode, CloudWatchResponse: $reply'); String? newSequenceToken = reply!['nextSequenceToken']; _sequenceToken = newSequenceToken; } else { - if (_verbosity > 0) { - print( - 'CloudWatch ERROR: StatusCode: $statusCode, CloudWatchResponse: $reply'); - } + _debugPrint(0, + 'CloudWatch ERROR: StatusCode: $statusCode, CloudWatchResponse: $reply'); throw new CloudWatchException( 'CloudWatch ERROR: StatusCode: $statusCode, CloudWatchResponse: $reply'); } diff --git a/pubspec.lock b/pubspec.lock index 519de5e..2d22232 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: name: aws_request url: "https://pub.dartlang.org" source: hosted - version: "0.1.6" + version: "0.1.7" boolean_selector: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 190d1c8..8ce94e0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: aws_cloudwatch description: An AWS CloudWatch wrapper package for easy Flutter cloud logging. Currently only logging is supported. -version: 0.1.12 +version: 0.2.0 homepage: https://github.com/Zsmerritt/Flutter_AWS_CloudWatch environment: @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter - aws_request: ^0.1.6 # Make request to AWS + aws_request: ^0.1.7 # Make request to AWS synchronized: ^3.0.0 # Synchronize requests to ensure valid keys universal_io: ^2.0.0 # Web support