cute_logger 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7bb49f4e102b7d0827d84b93296911db889deabb
4
- data.tar.gz: 9c5c17882b1d330543ca825de39e016ad4bb19af
3
+ metadata.gz: 35f4723eac7384b0d7e3c4361883830d178cb6f6
4
+ data.tar.gz: f43c61f6d84d4efdb128b5bab4c5df6c93a193d3
5
5
  SHA512:
6
- metadata.gz: e89de94763e3843f36119cfa5b18af5ab4a7b98a36a794eeb2a109a1b934e8ee31e0afd32553f9f4ba74e59316227df842437ca13c50134af508ce93f1630197
7
- data.tar.gz: d5f125d22a65492b02e24179c9749b4e87ac52e0745bef2e5e4e6f13392ed949822eeff1c8bc6a51cfedbb6bf3d96d7c277e7795ae5cf8190b42adee0ff5001f
6
+ metadata.gz: 49ff3b09c923bc05d50e8d039e882b8905b242bc66d77b4d6f4678eeafa3b38918def050a53ae76e120429dc303a5444b9b6f75f290b5d6e3bf2710bc8b1b52e
7
+ data.tar.gz: ee3e0e8d6a4254d958055a7ed4aea6b6f7e96f2fce47787490a80bd3d2df67dfb151573ce058122c9e1c1748ff5c05b7aff68b0b112e66e9c56964543856cc8b
data/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Cute Logger
2
2
 
3
- This gem provides methods to log events in an easy way and accessible from anywhere.
3
+ This gem provides accesible methods for doing the application logging in a simple manner.
4
+
5
+ ## Description
6
+
7
+ Cute Logger provides globally accesible methods to do the logging. It also provides a log parser
8
+ command for easy view during development. The gem includes mechanisms for log rotation, improved
9
+ exception logging and nice formatted log viewing among many other features and best practices.
10
+
11
+ Please refer to the document [Better Logging](docs/better_logging.md) for a better understanding of the functionality of Cute Logger.
4
12
 
5
13
  ## Installation
6
14
 
@@ -10,15 +18,25 @@ Add this line to your application's Gemfile:
10
18
  gem 'cute_logger'
11
19
  ```
12
20
 
21
+ And then execute:
22
+
23
+ ```bash
24
+ $ bundle update
25
+ ```
26
+
13
27
  Or install it yourself as:
14
28
 
15
- $ gem install cute_logger
29
+ ```bash
30
+ $ gem install cute_logger
31
+ ```
16
32
 
17
33
  ## Usage
18
34
 
19
- To use this gem, require it into your application and optionally call the setup function to specify how the information should be stored.
35
+ To use this gem, require it into your application and **optionally** call the setup function to specify how the log information should be stored, for how long and the minimum accepted severity.
36
+
37
+ ```ruby
38
+ require 'cute_logger'
20
39
 
21
- ```
22
40
  CuteLogger.setup(
23
41
  filename: 'application.log',
24
42
  severity: 'INFO',
@@ -27,24 +45,111 @@ CuteLogger.setup(
27
45
  )
28
46
  ```
29
47
 
48
+ The previous values are actually the **default** ones if the `setup` method is not explicitly called.
49
+
30
50
  To log something you could use the following formats:
31
51
 
32
- ```
33
- log_info('Some text')
34
- log_info(status: 'Working', value: '123')
52
+ ```ruby
53
+ log_info('Some event')
54
+ log_info('Some event', status: 'Working', value: '123')
35
55
  log_debug(my_hash)
36
56
  log_debug { 'Delayed evaluation' }
37
57
  log_info('MyAppName') { 'Something to log' }
38
58
  log_error('Error X', my_exception)
39
59
  ```
40
60
 
41
- There is an utility script that helps to visualize the contents of the log. For example:
61
+ Hashes and arrays are logged as JSON format:
62
+
63
+ ```ruby
64
+ my_array = {a: 'letter A', b: [1, 2, 3]}
65
+ log_info('Useful data', data: my_array)
66
+ ```
67
+
68
+ Results in an entry like the following:
69
+
70
+ ```bash
71
+ 2017-04-21 22:12:56 -0500,INFO,a801,3ff44803f9f4,Object,["Useful data",{"data":{"a":"letter A","b":["1","2","3"]}}]
72
+ ```
73
+
74
+ To view the log in a cute format (awesome_print):
75
+
76
+ ```bash
77
+ $ cat application.log | cute_log
78
+ ```
79
+
80
+ ```bash
81
+ 2017-04-21 22:12:56 -0500 INFO 43009-3ff44803f9f4 (Object)
82
+ [
83
+ [0] "Useful data",
84
+ [1] {
85
+ "data" => {
86
+ "a" => "letter A",
87
+ "b" => [
88
+ [0] "1",
89
+ [1] "2",
90
+ [2] "3"
91
+ ]
92
+ }
93
+ }
94
+ ]
95
+ ```
96
+
97
+ Exceptions have their own formatting:
42
98
 
99
+ ```ruby
100
+ begin
101
+ nil.hello
102
+ rescue => error
103
+ log_error('Error during X event', error: error)
104
+ end
43
105
  ```
106
+
107
+ ```bash
44
108
  $ cat application.log | cute_log
109
+ ```
110
+
111
+ ```ruby
112
+ 2017-04-21 22:18:28 -0500 ERROR 44691-3fe53703fa14 (Object)
113
+ [
114
+ [0] "Error during X event",
115
+ [1] {
116
+ "error" => {
117
+ "class" => "NoMethodError",
118
+ "message" => "undefined method `hello' for nil:NilClass",
119
+ "backtrace" => [
120
+ [ 0] "(irb):3:in `irb_binding'",
121
+ [ 1] "/Users/johndoe/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87:in `eval'",
122
+ [ 2] "/Users/johndoe/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87:in `evaluate'",
123
+ [ 3] "/Users/johndoe/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/context.rb:380:in `evaluate'",
124
+ [ 4] "/Users/johndoe/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:489:in `block (2 levels) in eval_input'",
125
+ ... log intentionally cutted down for better legibility ...
126
+ ]
127
+ }
128
+ }
129
+ ]
130
+ ```
131
+
132
+
133
+ The `cute_log` script utility helps to visualize the contents of the log. For example:
134
+
135
+ ```
136
+ # View the all the logs
137
+ $ cat application.log | cute_log
138
+
139
+ # View the logs in real time with awesome print
45
140
  $ tail -F application.log | cute_log
141
+
142
+ # View the logs in real time with JSON pretty_generate
46
143
  $ tail -F application.log | cute_log --json
144
+
145
+ # View all errors with awesome print (The switch --awesome is the default anyway)
47
146
  $ grep "ERROR" application.log | cute_log --awesome
147
+
148
+ # View all errors of ID 223
149
+ $ grep "ERROR" application.log | grep "ID000233" | cute_log
150
+
151
+ # View all warns from Jaunuary 2017
152
+ $ grep "WARN" application.log | grep "2017-01" | cute_log
48
153
  ```
49
154
 
50
155
  ## Development
data/cute_logger.gemspec CHANGED
@@ -9,8 +9,11 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Jorge Del Rio']
10
10
  spec.email = ['jdelrios@gmail.com']
11
11
 
12
- spec.summary = 'Gem to simplify and centralize the logging process'
13
- spec.description = 'This gem provides methods to log events to an unique place'
12
+ spec.summary = 'This gem provides accesible methods for doing the application logging in a simple manner'
13
+ spec.description = 'Cute Logger provides globally accesible methods to do the logging. It also provides a' +
14
+ ' log parser command for easy view during development. The gem includes mechanisms for' +
15
+ ' log rotation, improved exception logging and nice formatted log viewing among many' +
16
+ ' other features and best practices.'
14
17
  spec.homepage = 'https://github.com/newint33h/cute_logger'
15
18
  spec.license = 'MIT'
16
19
 
@@ -20,6 +23,7 @@ Gem::Specification.new do |spec|
20
23
  spec.require_paths = ['lib']
21
24
 
22
25
  spec.add_runtime_dependency 'awesome_print', '~> 1'
26
+ spec.add_runtime_dependency 'utf8_converter', '~> 0.1'
23
27
 
24
28
  spec.add_development_dependency 'bundler', '~> 1.10'
25
29
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -0,0 +1,275 @@
1
+ # Better Logging
2
+ One of the main purposes of logging is to be able to debug an application in case of a system failure. After thinking for a while about how we should log all the information to make it effective for debugging, I ended up with a bunch of rules we had to implement in the new gem to have quality logs. Some of such rules are:
3
+
4
+ * To be integrable with third party log viewers,
5
+ * To be multithreaded,
6
+ * To be Searchable searchable and
7
+ * To have meaningful output.
8
+
9
+ The main goal is to debug an application in case of error. However, there are many other cases to consider when logging, like how the application can be audited to determine if someone is hacking the system, or responding questions of how many times certain event happen with specific conditions. Or simply determine what changes were made by some employee. In any case, writing the logs in the right format can help you in the future to answer all these questions and more.
10
+
11
+ ## Rules for a good logging system
12
+ Let's look at a couple of good practices that can help us create a good logging system. These are a set of rules that we implemented in our logging gem.
13
+
14
+ ### One line logs
15
+ Logs that are one line long are perfect for being searched using console commands like `grep` without having to get the lines after and before to understand the log meaning. It is also easier for a log parser to determine where the log starts and ends. The line length can be any size, but one line.
16
+
17
+ ```
18
+ # The next log is in one line, no matter the if log data contains multiple lines. Lines are "squashed" into a single log line
19
+ 2016-09-11 14:04:51 -0500,ERROR,17083,3ffbceb4f99c,MyApp,["Something happen",{"result":"Some large text\nmultiline"}]
20
+ ```
21
+
22
+ Even if the log content has new line elements by the nature of the data, these are escaped to encapsulate the full log entry in one line.
23
+
24
+ ### Encoded User Input
25
+ All data that comes from the user must be encoded to avoid messing with special characters. A good format option for encoding the user input is using JSON, because this format does not use RETURNs and escapes special characters. It is important to ensure that the logging function encodes the logs in one charset. UTF-8 is very good choice for general purpose logs, however you should choose the encoding that best fits your needs.
26
+
27
+ ```
28
+ # The next log contains carriage return characters encoded in JSON
29
+ 2016-09-11 14:04:51 -0500,ERROR,17083,3ffbceb4f99c,MyApp,["Something happen",{"result":"Some large text\nmultiline\nline 3"}]
30
+ ```
31
+
32
+ ### Time and Timezone
33
+ Always log the time in UTC or ensure that your logs contain the correct timezone, and leave the job of displaying the time in local timezone to the tool in charge of visualizing the logs. Having milliseconds in the log's time is very useful to debug logs generated in the same server, unless you have all your servers in sync. As a suggestion, synchronize your servers with a NTP daemon.
34
+
35
+ ```
36
+ # The next log contains the time encoded in UNIX timestamp format
37
+ 1473620691361,ERROR,17083,3ffbceb4f99c,MyApp,["Something happen",{"result":"Some large text\nmultiline"}]
38
+ ```
39
+
40
+ ### Boilerplate log fields
41
+ There are some fields that always should be present in any log, like the time, severity, process ID, thread ID, and application identifier. The time and severity fields are obvious, but the process ID and thread ID are not. The process ID can identify the logs of an specific application if you are centralizing logs of many servers. Since the process ID values are limited to a short range and can collide among different servers, it is sometimes useful to add an unique machine identifier to the log. The thread ID is useful in any multi-threaded application to identify logs of a thread. In web development this is more important because with this field you can filter the logs corresponding to a single request. And finally the application identifier field is useful for filtering logs in a centralized log database.
42
+
43
+ All this fields should be abstracted in a log function that the application uses as the default log method. With this approach, the task of adding logs with all this information will be very simple for users o the logging gem.
44
+
45
+ ```
46
+ # Time, Severity, Process ID, Thread ID, Application Tag, Message in JSON
47
+ 2016-09-29 16:04:51 -0500,ERROR,17083,3ffbceb4f99c,Class,["Something happen",{"result":"Some large text\nmultiline"}]
48
+ ```
49
+
50
+
51
+ ## Rules for effective logging
52
+ Having a gem that implements the mentioned features is not even half of the way to have quality logs. As a developer, we need to follow some rules about how to write logs properly.
53
+
54
+ ### Logging enough information
55
+ A good log must have all the variables needed to read the code and understand what path the execution took. That way, the programmer can reproduce the execution path by reading the log.
56
+
57
+ ```ruby
58
+ def do_something(id, index, value_x)
59
+ random_value = rand(100)
60
+
61
+ # Logging all the variables to ensure an easy analysis in the future
62
+ log_debug('Something happen', id: id, index: index, value_x: value_x, random_value: random_value)
63
+ ...
64
+ end
65
+ ```
66
+
67
+ ### Multilevel error logs
68
+ A good code is divided in different layers that have a specific function. Logging the same log in different layers is a good practice as long as each layer is tagged properly and the information is not duplicated. For example, a service that consults via web service the actual exchange rate of dollars to another currency may have a connection timeout error, and that should log the request exception with the parameters needed to reproduce the error. But it's also possible to create another log entry in an upper layer to indicate that the operation to check the current exchange rate failed. Moreover, it is possible to generate a third log entry in the uppermost layer indicating that the action requested by the user failed. Each layer knows the context in which the execution is taking place, and that knowledge should be reflected in logs.
69
+
70
+ For the sake of simplicity, I wrote pseudocode with mixed Javascript and Ruby:
71
+
72
+ ```javascript
73
+ function on_click(button) {
74
+ value_a = $("value1Input").val();
75
+ value_b = $("value2Input").val();
76
+ x = business_rule(value_a, value_b); # Function to get the result from the backend
77
+ if (x.error) {
78
+ # The only error handling to do here is to notify the user about the problem
79
+ alert(x.error);
80
+ } else {
81
+ $("result").val(x.result);
82
+ }
83
+ }
84
+ ```
85
+
86
+ ```ruby
87
+ def business_rule(value_a, value_ b)
88
+ try
89
+ a = query_service(value_a)
90
+ return a / value_b
91
+ catch DivisionByZeroException
92
+ # No log required because we know how to handle it
93
+ return a # Business rule dictates that when value_b is zero, the default is 1.
94
+ catch NotFoundException
95
+ return 0 # Business rule dictates that if value_a is not found in the service, return 0
96
+ end
97
+ end
98
+
99
+ def query_service(value)
100
+ try
101
+ result = HTTP.request(url, data: {value: value}) # The service returns 404 if the value is not found and that raises an NotFoundException
102
+ return result.body
103
+ catch TimeoutException
104
+ # We need to log, probably if we see many warnings we can decide to switch to another provider
105
+ log_warn('Connection timeout with service X', value: value)
106
+ redo
107
+ end
108
+ end
109
+ ```
110
+
111
+ ### Protect confidential information
112
+ Confidential information must NOT be logged. Instead of logging sensitive information, we must log IDs that a person with authority can relate with the real data. The log registry must be confidential and should be used only by a limited number of people. Avoiding logging confidential information is an always welcome protection to guarantee the privacy of clients and reduce the risk of a data breach.
113
+
114
+ ```ruby
115
+ # Wrong
116
+ log_debug('User balance changed', name: data[:name], account_balance: data[:account_balance])
117
+
118
+ # Right
119
+ log_debug('User balance changed', user_id: data[:user_id], account_balance: data[:account_balance])
120
+ ```
121
+
122
+ ### Logs everywhere
123
+ All paths of the code must have a log entry, enough to tell a story of the execution of the application. Very general paths must be logged using INFO severity, and very deep and detailed paths must be logged using DEBUG severity. If a code has a know issue that may affect the users, a log with WARN severity is a good way to keep that issue in the aim.
124
+
125
+ ```ruby
126
+ def do_something_important(x, y)
127
+ # A log to indicate that an important action has started
128
+ log_info('Some important', x: x, y: y)
129
+
130
+ if x + y < 0
131
+ # Warn about this special case that may cause problems
132
+ log_warn('Special case of something', sum: x + y)
133
+ end
134
+
135
+ total = (x + y) * CONSTANT_Z + random(5) # A complex formula
136
+ # Log detailed information about this complex formula for debugging
137
+ log_debug("Result of complex formula of something", total: total)
138
+
139
+ rescue => error
140
+ # If something unexpected happend, log it
141
+ log_error('Error executing something', error: error)
142
+ end
143
+ ```
144
+
145
+ ### Global Exception Handler
146
+ A global exception handler must be defined to log all exceptions, and this is a log with FATAL severity. This ensures that any problem not foreseen can be logged.
147
+
148
+ ```ruby
149
+ # This will catch all the exceptions and generate a fatal severity log.
150
+ def global_exeception_handler(error)
151
+ log_fatal("Fatal error", error: error)
152
+ end
153
+ ```
154
+
155
+ ### Countable logs
156
+ A good log is something that can be counted. For example, the message that logs the user sign in should only contain "User signin" without any other information in the message. This allows a simple parser to split the log using commas and look for the exact message without worrying about special characters submitted by the user and affecting the parsing. This way, it is possible to generate metrics counting logs. Any additional information that needs to be logged can be added in an additional log fields.
157
+
158
+ ```ruby
159
+ # Wrong
160
+ log_info("User login: #{user_id}")
161
+
162
+ # Right
163
+ log_info('User login', user_id: user_id)
164
+ ```
165
+
166
+ ### Additional log fields
167
+ Almost all logs have a context of execution in which there is at least one object ID that is the protagonist of all the action. That should be logged as an additional field in the log and NOT as part of the message.
168
+ There may be additional fields that can be considered essential and must always be logged. For example, if an application can only work with a signed user, the log function must always log the signed user by default. Sometimes the application may have very well defined responsibilities and adding a tag may be very useful. For example, an application may want to differentiate among network operations and business rules. The tag NETWORK may be used for logs related to the code that establish the connection with a service, and the tag BUSINESS may be used to log information about the logic in the application.
169
+
170
+ ```ruby
171
+ # Using tags to group logs and simplify future searches
172
+ log_warn('Network failure', tag: 'NETWORK', ...)
173
+ log_warn('Calculating loan interest', tag: 'BUSINESS' loan: loan_id, interest: loan_interest)
174
+ ```
175
+
176
+ ### Log chaining
177
+ Design logs to be chainable, in other words, that one log can lead you to identify a bunch of other logs. For example, If you want to know what happened with the request of the person X, first search for the log message 'User signin' of user 'X'. That log must have a thread ID that should allow you to search for all the actions that happened during the request. This way, it is not needed to include the user's name in all logs.
178
+
179
+ ```ruby
180
+ log_info('User login', user_id: user_id, name: user_name)
181
+ ```
182
+
183
+ ```bash
184
+ $ grep "John Doe" application.log
185
+
186
+ 2016-09-11 14:04:51 -0500,INFO,17083,3ffbceb4f99c,MyApp,["User login",{"user_id":"2123","name":"John Doe"}]
187
+
188
+ $ grep "3ffbceb4f99c" application.log
189
+
190
+ 2016-09-11 14:04:51 -0500,INFO,17083,3ffbceb4f99c,MyApp,["Load permissions",{"permissions":"RW"}]
191
+ 2016-09-11 14:04:51 -0500,INFO,17083,3ffbceb4f99c,MyApp,["Load Preferences",{"preferences":{"font-size":"34","background-color":"green"}}]
192
+ ```
193
+
194
+ ### Rethrow vs throw new exceptions
195
+ There is a very thin line in between when to throw a new exception and when rethrow the last exception. Rethrow preserves the original message and line code of where the error raised while a new exception may contain different information depending of the context. Both possibilities are valid only when the actual code does not know how to handle the error properly and we need to transfer the responsibility to another part of the application.
196
+
197
+ Throwing new exception is useful when actual layer has additional information that may be useful for future purposes. Also is a good practice to throw new exception on each application layer, so a person interested in the business logic can filter for the error messages in that layer and have a meaningful error log.
198
+
199
+ Rethrowing the same exception is useful when you don't know how to handle the exception. For example, a code that query a service may handle a connection timeout exception by trying again, but a wrong credentials exception will require to rethrow the exception hoping that an upper layer knows how to handle it. When throwing a new exception, logging the old exception is a must, and when rethrowing the last exception the log is not needed.
200
+
201
+ Another approach is to always throw new exceptions nesting the previous exception in a new one. This allows to see how the exception bubbled up preserving the original error message and how this exception affects the different layers.
202
+
203
+ ```ruby
204
+ # If is important, log the parameters in the error
205
+ def a_method(x, y)
206
+ try
207
+ do_something_dangerous()
208
+ catch NiceAndExpectedError => error
209
+ # no log required, this was expected
210
+ return DEFAULT_VALUE
211
+ catch CustomError => error
212
+ # An error we know how to handle
213
+ log_warn('Error happen', x: x, y: y, error: error)
214
+ return workaround_method(x, y)
215
+ catch UnexpectedError => error
216
+ # We don't know how to handle this, so notify the user and do nothing
217
+ log_error('Error happen', x: x, y: y, error: error)
218
+ notify_user(error) # This is not the right place to do this, but you get the idea
219
+ abort() # Kill the thread/request, or simply ensure to do nothing after finishing this method
220
+ catch SpecialCaseError => error
221
+ # Log parameters for this special case and throw a new exception more manageable to the upper layer
222
+ log_warn('Special case triggered', x: x, y: y, error: error)
223
+ raise AnotherError.new('Error doing something')
224
+ catch StandardError => error
225
+ # Rethrowing the error, someone else's problem. (Is the same as not having this catch)
226
+ raise error
227
+ end
228
+ end
229
+ ```
230
+
231
+ ### Error resolution
232
+ Many errors can't be resolved by the application itself and require special attention. In these cases, the only solution is to inform the user about the problem and log the error with the proper severity. Some other errors are solved as time passes and some when the services recover itself, and in that case, the solution is to inform the user to try again later. In those examples, the error resolution is handled in the UI layer, and there is the place to catch the exception and log the error.
233
+
234
+ ```ruby
235
+ get '/users' do
236
+ try
237
+ users = Database.get_users()
238
+ catch CustomError => error
239
+ log_error('Failed to retrieve users', error: error)
240
+ json_response({"status": "error", "message": error.message}) # Let the front end handle this
241
+ end
242
+ end
243
+ ```
244
+
245
+ ### Common ways to group and read logs
246
+ It is important to keep in mind the usual ways of reading logs, so the programmers can write their logs thinking in how effective they will be.
247
+
248
+ **Chronological** - Reading the logs sorted by time is the most common way of understanding what is happening, however this may be very hard to read if the logs are mixed with different threads executing the same actions.
249
+
250
+ **Severity** - This is useful if you want to view the errors in the system to pick one and solve it. But only useful for FATAL and ERROR severity.
251
+
252
+ **Thread ID** - This is very useful to read an history of one execution flow of an application.
253
+
254
+ **Tag** - Useful to only show logs related to an specific area or application layer.
255
+
256
+ **User** - Very useful to trace what was the user doing. This helps a lot to detect corner cases that the user triggers due their uncommon behaviour with the application.
257
+
258
+ **ID** - Using custom IDs to identify a resource can help you filter all the logs that has something to do with the given ID.
259
+
260
+ ### Log severities
261
+ Identify the proper severity for the logs is essential to have an effective problem identification.
262
+
263
+ **FATAL** is when the immediate intervention is needed and the system can't continue running. (This should raise the alarms somewhere in your office).
264
+ **ERROR** is when something needs a fix because the system is failing and the information may be losing.
265
+ **WARN** is when there is potentially an error that may affect some the system. Also a warning could be issued when there is technical debt or something that is not fully implemented.
266
+ **INFO** is when you need to inform about an important event that is useful to determinate the lifecycle of the execution.
267
+ **DEBUG** is basically anything the programmer want to log to have better visibility of the values of the application in some part of the code.
268
+
269
+ ## Summary
270
+ A lot can be said of how to treat logging in an application, but the idea here was to shed some light on tips and techniques that I have found to be useful to cope with the ever growing amount of information that is being produced by nowadays production systems.
271
+
272
+ Logging is a difficult task. We feel there is no correct or incorrect approach to logging, and how to implement it correctly depends on the needs of your system. Nevertheless we hope that this brief article provides some useful ideas.
273
+
274
+ This gem was inspired by a private gem developed at kueski.com, aswell this article which was slightly modified to be released in the public domain. Please refer to the original article at:
275
+ [http://nerds.kueski.com/better-logging/](http://nerds.kueski.com/better-logging/)
data/lib/cute_logger.rb CHANGED
@@ -2,7 +2,7 @@ require 'cute_logger/version'
2
2
  require 'logger'
3
3
  require 'json'
4
4
  require 'awesome_print'
5
- require_relative 'utf8_enforcer'
5
+ require 'utf8_converter'
6
6
 
7
7
  # This module defines the functionality the the CuteLogger gem
8
8
  module CuteLogger
@@ -1,5 +1,5 @@
1
1
 
2
2
  # Partial module to define the version of the gem
3
3
  module CuteLogger
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cute_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jorge Del Rio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-21 00:00:00.000000000 Z
11
+ date: 2017-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: utf8_converter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +80,10 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '5'
69
- description: This gem provides methods to log events to an unique place
83
+ description: Cute Logger provides globally accesible methods to do the logging. It
84
+ also provides a log parser command for easy view during development. The gem includes
85
+ mechanisms for log rotation, improved exception logging and nice formatted log viewing
86
+ among many other features and best practices.
70
87
  email:
71
88
  - jdelrios@gmail.com
72
89
  executables:
@@ -80,9 +97,9 @@ files:
80
97
  - Rakefile
81
98
  - bin/cute_log
82
99
  - cute_logger.gemspec
100
+ - docs/better_logging.md
83
101
  - lib/cute_logger.rb
84
102
  - lib/cute_logger/version.rb
85
- - lib/utf8_enforcer.rb
86
103
  homepage: https://github.com/newint33h/cute_logger
87
104
  licenses:
88
105
  - MIT
@@ -106,5 +123,6 @@ rubyforge_project:
106
123
  rubygems_version: 2.5.1
107
124
  signing_key:
108
125
  specification_version: 4
109
- summary: Gem to simplify and centralize the logging process
126
+ summary: This gem provides accesible methods for doing the application logging in
127
+ a simple manner
110
128
  test_files: []
data/lib/utf8_enforcer.rb DELETED
@@ -1,27 +0,0 @@
1
- # String extensions to convert any encoding to utf8
2
- class String
3
- def try_convert_from_encoding_to_utf8!(encoding)
4
- original_encoding = self.encoding
5
- begin
6
- force_encoding(encoding).encode!(Encoding::UTF_8)
7
- true
8
- rescue
9
- force_encoding(original_encoding)
10
- false
11
- end
12
- end
13
-
14
- def to_utf8!
15
- if force_encoding(Encoding::UTF_8).valid_encoding?
16
- return encode!(Encoding::UTF_8, invalid: :replace, replace: '?')
17
- end
18
- return self if try_convert_from_encoding_to_utf8!(Encoding::ISO_8859_1)
19
- return self if try_convert_from_encoding_to_utf8!(Encoding::Windows_1252)
20
- return self if try_convert_from_encoding_to_utf8!(Encoding::Windows_1252)
21
- encode!(Encoding::UTF_8, invalid: :replace, replace: '?')
22
- end
23
-
24
- def to_utf8
25
- dup.to_utf8!
26
- end
27
- end