oslg 0.2.7 → 0.2.9

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
  SHA256:
3
- metadata.gz: 6309b9c37cd0135fc85fd44a2903d7594ccf1b0d952f64cec3df1b7c9d5f32e9
4
- data.tar.gz: 1d4b53beb732dd9d0680f59e79e1d078f5d4d0b2289bfe3ac8f224bae3bb0ff4
3
+ metadata.gz: f6af1c266df1a21c24e1f810ae3a13ea4b8cee514ef522860f67c94e0108faca
4
+ data.tar.gz: ecc6bdccad1d9e3de77eb27f17e9d63b82aa290f982dd3a525f786de576341d3
5
5
  SHA512:
6
- metadata.gz: 1edc4f411a77d1aaa0e2c6d48a9847ef3239af027d4699894519a8f1286b639c4a11dbd6bc96c2ef1cec43047d0601b5d01d38f178efde2e638786e890103b5a
7
- data.tar.gz: 29899ed065067829900502b40ecd053c354a9255954bc18a1b735c30aaf1d6edab6a5c369a37af01b63e5330ef0b27cd8c4855dbecadfc352d1e5733b18f7ff0
6
+ metadata.gz: 107bf656388646393a97f60a3a49ddaf3f23764c4f8f91445d131813ec33c53c699a7f25f2e6f90058f23faa93eeb1d5abdeb48f6260ae36f99402a4ab91b4cd
7
+ data.tar.gz: 5a4bd5a3de4d1d0e96c274e31c63cdee2fec3adc470c88881225ebc475d8b91362585766197dd37110565f7480792bfd2523423bba6847158e2c16ad54bb5e05
@@ -6,87 +6,7 @@ on:
6
6
  - dev
7
7
 
8
8
  jobs:
9
- test_300x:
10
- runs-on: ubuntu-22.04
11
- steps:
12
- - name: Check out repository
13
- uses: actions/checkout@v2
14
- - name: Run Tests
15
- run: |
16
- echo $(pwd)
17
- echo $(ls)
18
- docker pull nrel/openstudio:3.0.0
19
- docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.0.0
20
- docker exec -t test pwd
21
- docker exec -t test ls
22
- docker exec -t test bundle update
23
- docker exec -t test bundle exec rake
24
- docker kill test
25
- test_321x:
26
- runs-on: ubuntu-22.04
27
- steps:
28
- - name: Check out repository
29
- uses: actions/checkout@v2
30
- - name: Run Tests
31
- run: |
32
- echo $(pwd)
33
- echo $(ls)
34
- docker pull nrel/openstudio:3.2.1
35
- docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.2.1
36
- docker exec -t test pwd
37
- docker exec -t test ls
38
- docker exec -t test bundle update
39
- docker exec -t test bundle exec rake
40
- docker kill test
41
- test_330x:
42
- runs-on: ubuntu-22.04
43
- steps:
44
- - name: Check out repository
45
- uses: actions/checkout@v2
46
- - name: Run Tests
47
- run: |
48
- echo $(pwd)
49
- echo $(ls)
50
- docker pull nrel/openstudio:3.3.0
51
- docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.3.0
52
- docker exec -t test pwd
53
- docker exec -t test ls
54
- docker exec -t test bundle update
55
- docker exec -t test bundle exec rake
56
- docker kill test
57
- test_340x:
58
- runs-on: ubuntu-22.04
59
- steps:
60
- - name: Check out repository
61
- uses: actions/checkout@v2
62
- - name: Run Tests
63
- run: |
64
- echo $(pwd)
65
- echo $(ls)
66
- docker pull nrel/openstudio:3.4.0
67
- docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.4.0
68
- docker exec -t test pwd
69
- docker exec -t test ls
70
- docker exec -t test bundle update
71
- docker exec -t test bundle exec rake
72
- docker kill test
73
- test_351x:
74
- runs-on: ubuntu-22.04
75
- steps:
76
- - name: Check out repository
77
- uses: actions/checkout@v2
78
- - name: Run Tests
79
- run: |
80
- echo $(pwd)
81
- echo $(ls)
82
- docker pull nrel/openstudio:3.5.1
83
- docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.5.1
84
- docker exec -t test pwd
85
- docker exec -t test ls
86
- docker exec -t test bundle update
87
- docker exec -t test bundle exec rake
88
- docker kill test
89
- test_361x:
9
+ test_oslg:
90
10
  runs-on: ubuntu-22.04
91
11
  steps:
92
12
  - name: Check out repository
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # oslg
2
2
 
3
- A logger module for _picky_ [OpenStudio](https://openstudio.net) [Measure](https://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/) developers who wish to select what gets logged to which target (e.g. OpenStudio _runner_ vs custom JSON file). Add:
3
+ A logger, initially for _picky_ [OpenStudio](https://openstudio.net) [Measure](https://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/) developers who wish to select what gets logged to which target (e.g. OpenStudio _runner_ vs custom JSON files). Yet __oslg__ has no OpenStudio dependency; it can be integrated within any other environment. Just add:
4
4
 
5
5
  ```
6
6
  gem "oslg", git: "https://github.com/rd2/oslg", branch: "main"
7
7
  ```
8
8
 
9
- ... in a v2.1 [bundled](https://bundler.io) _Measure_ development environment "Gemfile" (or instead as a _gemspec_ dependency), and then run:
9
+ ... in a v2.1 [bundled](https://bundler.io) development environment "Gemfile" (or instead as a _gemspec_ dependency), and then run:
10
10
 
11
11
  ```
12
12
  bundle install (or 'bundle update')
@@ -14,7 +14,7 @@ bundle install (or 'bundle update')
14
14
 
15
15
  ### OpenStudio & EnergyPlus
16
16
 
17
- In most cases, critical (and many non-critical) OpenStudio anomalies will be caught by EnergyPlus at the start of a simulation. Standalone applications (e.g. _Apply Measures Now_) or [SDK](https://openstudio-sdk-documentation.s3.amazonaws.com/index.html)-based iterative solutions can't rely on EnergyPlus to catch such errors - and somehow warn users of potentially invalid results. This Ruby module provides developers a means to log warnings, as well as non-fatal & fatal errors, that may eventually put OpenStudio's (or EnergyPlus') internal processes at risk. Developers are free to decide how to harness __oslg__ as they see fit, e.g. output logged WARNING messages to the OpenStudio _runner_, while writing out DEBUG messages to a bug report file.
17
+ In most cases, critical (and many non-critical) OpenStudio anomalies will be caught by EnergyPlus at the start of a simulation. Standalone applications (e.g. _Apply Measures Now_) or [SDK](https://openstudio-sdk-documentation.s3.amazonaws.com/index.html) based iterative solutions can't rely on EnergyPlus to catch such errors - and somehow warn users of potentially invalid results. __oslg__ provides developers a means to log warnings, as well as non-fatal & fatal errors, that may eventually put OpenStudio's (or EnergyPlus') internal processes at risk. Developers are free to decide how to harness __oslg__ as they see fit, e.g. output logged WARNING messages to the OpenStudio _runner_, while writing out DEBUG messages to a bug report file.
18
18
 
19
19
  ### Recommended use
20
20
 
@@ -39,7 +39,7 @@ FATAL
39
39
 
40
40
  DEBUG messages aren't benign at all, but are certainly less informative for the typical Measure user.
41
41
 
42
- Initially, __oslg__ sets 2x internal attributes: `level` (INFO) and `status` (< DEBUG). The `level` attribute is a user-set threshold below which less severe logs (e.g. DEBUG) are ignored. For instance, if `level` were _reset_ to DEBUG (e.g. `M.reset(M::DEBUG)`), then all DEBUG messages would also be logged. The `status` attribute is reset with each new log entry when the latter's log level is more severe than its predecessors (e.g. `status == M::FATAL` if there is a single log entry registered as FATAL). To check the curent __oslg__ `status` (true or false):
42
+ Initially, __oslg__ sets 2 _global_ internal attributes: `level` (INFO) and `status` (< DEBUG). The `level` attribute is a user-set threshold below which less severe logs (e.g. DEBUG) are ignored. For instance, if `level` were _reset_ to DEBUG (e.g. `M.reset(M::DEBUG)`), then all DEBUG messages would also be logged. The `status` attribute is reset with each new log entry when the latter's log level is more severe than its predecessors (e.g. `status == M::FATAL` if there is a single log entry registered as FATAL). To check the curent __oslg__ `status` (true or false):
43
43
 
44
44
  ```
45
45
  M.debug?
@@ -54,7 +54,7 @@ It's sometimes not a bad idea to rely on a _clean_ slate (e.g. within RSpecs). T
54
54
  M.clean!
55
55
  ```
56
56
 
57
- EnergyPlus will run with e.g. out-of-range material or fluid properties, while logging ERROR messages in the process. It remains up to users to decide what to do with simulation results. We recommend something similar with __oslg__. For instance, we suggest logging as __FATAL__ any error that should halt Measure processes and prevent OpenStudio from launching an EnergyPlus simulation. This could be missing or poorly-defined OpenStudio files.
57
+ EnergyPlus will run with e.g. out-of-range material or fluid properties, while logging ERROR messages in the process. It remains up to users to decide what to do with simulation results. We recommend something similar with __oslg__. For instance, we suggest logging as __FATAL__ any error that should halt Measure processes and prevent OpenStudio from launching an EnergyPlus simulation. This could be missing or poorly formatted files.
58
58
 
59
59
  ```
60
60
  M.log(M::FATAL, "Missing input JSON file")
@@ -66,7 +66,7 @@ Consider logging non-fatal __ERROR__ messages when encountering invalid OpenStud
66
66
  M.log(M::ERROR, "Measure won't process MASSLESS materials")
67
67
  ```
68
68
 
69
- A __WARNING__ could be triggered from inherit limitations of the underlying Measure scope or methodology (something users may have little knowledge of beforehand). For instance, surfaces the size of dinner plates are often artifacts of poor 3D model design. It's usually not a good idea to have such small surfaces in an OpenStudio model, but neither OpenStudio nor EnergyPlus will necessarily warn users of such occurrences. It's up to users to decide on the suitable course of action.
69
+ A __WARNING__ could be triggered from inherit limitations of the underlying Measure scope or methodology (something users may have little knowledge of beforehand). For instance, surfaces the size of dinner plates are often artifacts of poor 3D modelling. It's usually not a good idea to have such small surfaces in an OpenStudio model, but neither OpenStudio nor EnergyPlus will necessarily warn users of such occurrences. It's up to users to decide on the suitable course of action.
70
70
 
71
71
  ```
72
72
  M.log(M::WARN, "Surface area < 100cm2")
@@ -78,13 +78,13 @@ There's also the possibility of logging __INFO__-rmative messages for users, e.g
78
78
  M.log(M::INFO, "Envelope compliant to prescriptive code requirements")
79
79
  ```
80
80
 
81
- Finally, a number of sanity checks are likely warranted to ensure Ruby doesn't crash (e.g., invalid access to uninitialized variables), especially for lower-level functions. We suggest implementing safe fallbacks when this occurs, but __DEBUG__ errors could nonetheless be triggered to signal a bug.
81
+ Finally, a number of sanity checks are likely warranted to ensure Ruby doesn't crash (e.g., invalid access to uninitialized variables), especially for lower-level functions. We suggest implementing safe fallbacks when this occurs, but __DEBUG__ errors could nonetheless be logged to signal buggy code.
82
82
 
83
83
  ```
84
84
  M.log(M::DEBUG, "Hash? expecting Array (method)")
85
85
  ```
86
86
 
87
- All log entries are stored in a single Ruby _Array_, with each individual log entry as a Ruby _Hash_ with 2x _keys_ ```:level``` and ```:message```, e.g.:
87
+ All log entries are stored in a single Ruby _Array_, with each individual log entry as a Ruby _Hash_ with 2 _keys_ ```:level``` and ```:message```, e.g.:
88
88
 
89
89
  ```
90
90
  M.logs.each do |log|
@@ -96,7 +96,7 @@ These logs can be first _mapped_ to other structures (then edited), depending on
96
96
 
97
97
  ### Preset log templates
98
98
 
99
- Typically, developers would first catch bad input, log an error message and possibly exit by returning an object (e.g. __false__, __nil__), e.g.:
99
+ Typically, developers would first catch bad input, log an error message and possibly exit by returning an object (e.g. __false__, __nil__), such as:
100
100
 
101
101
  ```
102
102
  unless var.is_a?(Array)
@@ -109,19 +109,19 @@ The following are __oslg__ one-liner methods that _log & return_ in one go. Thes
109
109
 
110
110
  ---
111
111
 
112
- __invalid__: for logging e.g. uninitialized or nilled objects:
112
+ __invalid__: for logging e.g. nilled objects or out-of-scope variables:
113
113
 
114
114
  ```
115
- return M.invalid("area", "sum", 0, M::ERROR, false) unless area
115
+ return M.invalid("area", "sum", 0, M::FATAL, false) if area > 1000000
116
116
  ```
117
117
 
118
- This logs an ERROR message informing users that an invalid object, 'area', was caught while running method 'sum', and then exits by returning _false_. The logged message would be:
118
+ This logs a FATAL error message informing users that an out-of-scope argument, 'area', was caught while running method 'sum', and then exits by returning _false_. The logged message would be:
119
119
 
120
120
  ```
121
121
  "Invalid 'area' (sum)"
122
122
  ```
123
123
 
124
- The 3rd argument (e.g. _0_) is ignored unless `> 0` - a useful option when asserting method arguments:
124
+ The 3rd parameter (e.g. _0_) is ignored unless `> 0` - a useful option when asserting method arguments:
125
125
 
126
126
  ```
127
127
  def sum(areas, units)
@@ -131,93 +131,91 @@ def sum(areas, units)
131
131
  end
132
132
  ```
133
133
 
134
- ... would generate the following if both `areas` and `units` arguments were for instance _nilled_:
134
+ ... would generate the following if both `areas` and `units` arguments were, for instance, _nilled_:
135
135
  ```
136
136
  "Invalid 'areas' arg #1 (sum)"
137
137
  "Invalid 'units' arg #2 (sum)"
138
138
  ```
139
139
 
140
- The first 2x __invalid__ method arguments (faulty object ID, calling method ID) are required. The remaining 3x arguments are optional; in such cases, __invalid__ `level` defaults to DEBUG, and __invalid__ returns _nil_).
140
+ The first 2 __invalid__ method parameters (faulty object ID, calling method ID) are required. The remaining 3 parameters are optional; in such cases, __invalid__ `level` defaults to DEBUG, and __invalid__ returns _nil_.
141
141
 
142
142
  ---
143
143
 
144
144
  __mismatch__: for logging incompatible instances vs classes:
145
145
 
146
146
  ```
147
- return M.mismatch("areas", areas, Array, "sum") unless areas.is_a?(Array)
147
+ return M.mismatch("area", area, Float, "sum") unless area.is_a?(Numeric)
148
148
  ```
149
149
 
150
- If 'areas' were for example a _String_, __mismatch__ would generate the following DEBUG log message (before returning _nil_):
150
+ If 'area' were for example a _String_, __mismatch__ would generate the following DEBUG log message (before returning _nil_):
151
151
 
152
152
  ```
153
- "'areas' String? expecting Array (sum)"
153
+ "'area' String? expecting Float (sum)"
154
154
  ```
155
155
 
156
- These 4x __mismatch__ arguments are required (an object ID, a valid Ruby object, the mismatched Ruby class, and the calling method ID). As a safeguard, __oslg__ will NOT log a _mismatch_ if the object is an actual instance of the class. As with __invalid__, there are 2x optional _terminal_ arguments, e.g. `M::ERROR, false)`.
156
+ These 4 __mismatch__ parameters are required (an object ID, a valid Ruby object, the mismatched Ruby class, and the calling method ID). As a safeguard, __oslg__ will NOT log a _mismatch_ if the object is an actual instance of the class. As with __invalid__, there are 2 optional _terminal_ parameters (e.g. `M::FATAL`, `false`).
157
157
 
158
158
  ---
159
159
 
160
160
  __hashkey__: for logging missing _Hash_ keys:
161
161
 
162
162
  ```
163
- return M.hashkey("faces", faces, :area, "sum") unless faces.key?(:area)
163
+ return M.hashkey("floor area", floor, :area, "sum") unless floor.key?(:area)
164
164
  ```
165
165
 
166
- If the _Hash_ `faces` does not hold `:area` as one of its keys, then __hashkey__ would generate the following DEBUG log message (before returning _nil_):
166
+ If the _Hash_ `floor` does not hold `:area` as one of its keys, then __hashkey__ would generate the following DEBUG log message (before returning _nil_):
167
167
 
168
168
  ```
169
- "Missing 'area' key in 'faces' Hash (sum)"
169
+ "Missing 'area' key in 'floor' Hash (sum)"
170
170
  ```
171
171
 
172
- Similar to __mismatch__, the method __hashkey__ requires 4x arguments (a _Hash_ ID, a valid Ruby _Hash_, the missing _key_, and the calling method ID). There are also 2x optional _terminal_ arguments, e.g. `M::ERROR, false)`.
172
+ Similar to __mismatch__, the method __hashkey__ requires 4 parameters (a _Hash_ ID, a valid Ruby _Hash_, the missing _key_, and the calling method ID). There are also 2 optional _terminal_ parameters (e.g. `M::FATAL`, `false`).
173
173
 
174
174
  ---
175
175
 
176
- __empty__: for logging empty _Enumerable_ (e.g. _Array_, _Hash_) instances or uninitialized boost optionals (e.g. uninitialized _ThermalZone_ object of an _OpenStudio Space_):
176
+ __empty__: for logging empty _Enumerable_ (e.g. _Array_, _Hash_) instances or uninitialized _Boost_ optionals (e.g. an uninitialized _ThermalZone_ object of an _OpenStudio Space_):
177
177
 
178
178
  ```
179
- return M.empty("faces", "sum", M::ERROR, false) if faces.empty?
179
+ return M.empty("zone", "conditioned?", M::FATAL, false) if space.thermalZone.empty?
180
180
  ```
181
181
 
182
- An empty `faces` _Hash_ would generate the following ERROR log message (before returning _false_):
182
+ An empty (i.e. uninitialized) `thermalZone` would generate the following FATAL error log message (before returning _false_):
183
183
 
184
184
  ```
185
- "Empty 'faces' (sum)"
185
+ "Empty 'zone' (conditioned?)"
186
186
  ```
187
187
 
188
- Again, the first 2x arguments are required; the last 2x are optional.
188
+ Again, the first 2 parameters are required; the last 2 are optional.
189
189
 
190
190
  ---
191
191
 
192
192
  __zero__: for logging zero'ed (or nearly-zero'ed) values:
193
193
 
194
194
  ```
195
- M.zero("area", "sum", M::FATAL, false) if area.zero?
196
- M.zero("area", "sum", M::FATAL, false) if area.abs < TOL
195
+ M.zero("floor area", "sum", M::FATAL, false) if floor[:area].abs < TOL
197
196
  ```
198
- ... generating the following FATAL log message (before returning _false_):
197
+ ... generating the following FATAL error log message (before returning _false_):
199
198
 
200
199
  ```
201
- "Zero 'area' (sum)"
202
- "Zero 'area' (sum)"
200
+ "Zero 'floor area' (sum)"
203
201
  ```
204
202
 
205
- And again, the first 2x arguments are required; the last 2x are optional.
203
+ And again, the first 2 parameters are required; the last 2 are optional.
206
204
 
207
205
  ---
208
206
 
209
207
  __negative__: for logging negative (< 0) values:
210
208
 
211
209
  ```
212
- M.negative("area", "sum", M::FATAL, false) if area < 0
210
+ M.negative("floor area", "sum", M::FATAL, false) if floor[:area] < 0
213
211
  ```
214
212
  ... generating this FATAL log message (before returning _false_):
215
213
 
216
214
  ```
217
- "Negative 'area' (sum)"
215
+ "Negative 'floor area' (sum)"
218
216
  ```
219
217
 
220
- You guessed it: the first 2x arguments are required; the last 2x as optionals.
218
+ You guessed it: the first 2 parameters are required; the last 2 as optionals.
221
219
 
222
220
  ---
223
221
 
data/lib/oslg/oslog.rb CHANGED
@@ -29,229 +29,285 @@
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
31
  module OSlg
32
- DEBUG = 1
33
- INFO = 2
34
- WARN = 3
35
- ERROR = 4
36
- FATAL = 5
37
-
38
- @@logs = []
39
- @@level = INFO
40
- @@status = 0
41
-
42
- @@tag = []
43
- @@tag[0 ] = ""
44
- @@tag[DEBUG] = "DEBUG"
45
- @@tag[INFO ] = "INFO"
46
- @@tag[WARN ] = "WARNING"
47
- @@tag[ERROR] = "ERROR"
48
- @@tag[FATAL] = "FATAL"
49
-
50
- @@msg = []
51
- @@msg[0 ] = ""
52
- @@msg[DEBUG] = "Debugging ..."
53
- @@msg[INFO ] = "Success! No errors, no warnings"
54
- @@msg[WARN ] = "Partial success, raised non-fatal warnings"
55
- @@msg[ERROR] = "Partial success, encountered non-fatal errors"
56
- @@msg[FATAL] = "Failure, triggered fatal errors"
32
+ DEBUG = 1 # e.g. for debugging e.g. "argument String? expecting Integer"
33
+ INFO = 2 # e.g. informative e.g. "success! no errors, no warnings"
34
+ WARN = 3 # e.g. warnings e.g. "partial success, see non-fatal warnings"
35
+ ERROR = 4 # e.g. erros e.g. "partial success, see non-fatal errors"
36
+ FATAL = 5 # e.g. failures e.g. "stopping! encountered fatal errors"
37
+
38
+ # each log is a Hash with keys :level (Integer) and :message (String)
39
+ @@logs = []
40
+
41
+ # preset strings matching log levels
42
+ @@tag = [
43
+ "", # (empty string)
44
+ "DEBUG", # DEBUG
45
+ "INFO", # INFO
46
+ "WARNING", # WARNING
47
+ "ERROR", # ERROR
48
+ "FATAL" # FATAL
49
+ ].freeze
50
+
51
+ # preset strings matching log status
52
+ @@msg = [
53
+ "", # (empty string)
54
+ "Debugging ...", # DEBUG
55
+ "Success! No errors, no warnings", # INFO
56
+ "Partial success, raised non-fatal warnings", # WARNING
57
+ "Partial success, encountered non-fatal errors", # ERROR
58
+ "Failure, triggered fatal errors" # FATAL
59
+ ].freeze
60
+
61
+ @@level = INFO # initial log level
62
+ @@status = 0 # initial status
57
63
 
58
64
  ##
59
- # Return log entries.
65
+ # Returns log entries.
60
66
  #
61
- # @return [Array] current log entries
67
+ # @return [Array<Hash>] log entries (see @@logs)
62
68
  def logs
63
69
  @@logs
64
70
  end
65
71
 
66
72
  ##
67
- # Return current log level.
73
+ # Returns current log level.
68
74
  #
69
- # @return [Integer] DEBUG, INFO, WARN, ERROR or FATAL
75
+ # @return [DEBUG, INFO, WARN, ERROR, FATAL] log level
70
76
  def level
71
77
  @@level
72
78
  end
73
79
 
74
80
  ##
75
- # Return current log status.
81
+ # Returns current log status.
76
82
  #
77
- # @return [Integer] DEBUG, INFO, WARN, ERROR or FATAL
83
+ # @return [0, DEBUG, INFO, WARN, ERROR, FATAL] log status
78
84
  def status
79
85
  @@status
80
86
  end
81
87
 
82
88
  ##
83
- # Return whether current status is DEBUG
89
+ # Returns whether current status is DEBUG.
84
90
  #
85
- # @return [Bool] true if DEBUG
91
+ # @return [Bool] whether current log status is DEBUG
86
92
  def debug?
87
93
  @@status == DEBUG
88
94
  end
89
95
 
90
96
  ##
91
- # Return whether current status is INFO
97
+ # Returns whether current status is INFO.
92
98
  #
93
- # @return [Bool] true if INFO
99
+ # @return [Bool] whether current log status is INFO
94
100
  def info?
95
101
  @@status == INFO
96
102
  end
97
103
 
98
104
  ##
99
- # Return whether current status is WARN
105
+ # Returns whether current status is WARN.
100
106
  #
101
- # @return [Bool] true if WARN
107
+ # @return [Bool] whether current log status is WARN
102
108
  def warn?
103
109
  @@status == WARN
104
110
  end
105
111
 
106
112
  ##
107
- # Return whether current status is ERROR
113
+ # Returns whether current status is ERROR.
108
114
  #
109
- # @return [Bool] true if ERROR
115
+ # @return [Bool] whether current log status is ERROR
110
116
  def error?
111
117
  @@status == ERROR
112
118
  end
113
119
 
114
120
  ##
115
- # Return whether current status is FATAL
121
+ # Returns whether current status is FATAL.
116
122
  #
117
- # @return [Bool] true if FATAL
123
+ # @return [Bool] whether current log status is FATAL
118
124
  def fatal?
119
125
  @@status == FATAL
120
126
  end
121
127
 
122
128
  ##
123
- # Return string equivalent of level
129
+ # Returns preset OSlg string that matches log level.
124
130
  #
125
- # @param level [Integer] DEBUG, INFO, WARN, ERROR or FATAL
131
+ # @param lvl [#to_i] 0, DEBUG, INFO, WARN, ERROR or FATAL
126
132
  #
127
- # @return [String] "DEBUG", "INFO", "WARN", "ERROR" or "FATAL"
128
- def tag(level)
129
- return @@tag[level] if level >= DEBUG && level <= FATAL
133
+ # @return [String] preset OSlg tag (see @@tag)
134
+ def tag(lvl)
135
+ return "" unless lvl.respond_to?(:to_i)
136
+
137
+ lvl = lvl.to_i
138
+ return "" if lvl < DEBUG
139
+ return "" if lvl > FATAL
140
+
141
+ @@tag[lvl]
130
142
 
131
- ""
132
143
  end
133
144
 
134
145
  ##
135
- # Return preset OSlg message linked to status.
146
+ # Returns preset OSlg message that matches log status.
136
147
  #
137
- # @param status [Integer] DEBUG, INFO, WARN, ERROR or FATAL
148
+ # @param stat [Integer] 0, DEBUG, INFO, WARN, ERROR or FATAL
138
149
  #
139
- # @return [String] preset OSlg message
140
- def msg(status)
141
- return @@msg[status] if status >= DEBUG && status <= FATAL
150
+ # @return [String] preset OSlg message (see @@msg)
151
+ def msg(stat)
152
+ return "" unless stat.respond_to?(:to_i)
153
+
154
+ stat = stat.to_i
155
+ return "" if stat < DEBUG
156
+ return "" if stat > FATAL
142
157
 
143
- ""
158
+ @@msg[stat]
144
159
  end
145
160
 
146
161
  ##
147
- # Set level.
162
+ # Converts object to String and trims if necessary.
148
163
  #
149
- # @param level [Integer] DEBUG, INFO, WARN, ERROR or FATAL
164
+ # @param txt [#to_s] a stringable object
165
+ # @param length [#to_i] maximum return string length
150
166
  #
151
- # @return [Integer] current level
152
- def reset(level)
153
- @@level = level if level >= DEBUG && level <= FATAL
167
+ # @return [String] a trimmed message string (empty unless stringable)
168
+ def trim(txt = "", length = 60)
169
+ length = 60 unless length.respond_to?(:to_i)
170
+ length = length.to_i if length.respond_to?(:to_i)
171
+ return "" unless txt.respond_to?(:to_s)
172
+
173
+ txt = txt.to_s.strip
174
+ txt = txt[0...length] + " ..." if txt.length > length
175
+
176
+ txt
154
177
  end
155
178
 
156
179
  ##
157
- # Log new entry.
180
+ # Resets level, if lvl (input) is within accepted range.
158
181
  #
159
- # @param level [Integer] DEBUG, INFO, WARN, ERROR or FATAL
160
- # @param message [String] user-provided message
182
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL
161
183
  #
162
- # @return [Integer] current status
163
- def log(level = DEBUG, message = "")
164
- if level >= DEBUG && level <= FATAL && level >= @@level
165
- @@logs << {level: level, message: message}
166
- @@status = level if level > @@status
167
- end
184
+ # @return [DEBUG, INFO, WARN, ERROR, FATAL] updated/current level
185
+ def reset(lvl = DEBUG)
186
+ return @@level unless lvl.respond_to?(:to_i)
168
187
 
169
- @@status
188
+ lvl = lvl.to_i
189
+ return @@level if lvl < DEBUG
190
+ return @@level if lvl > FATAL
191
+
192
+ @@level = lvl
170
193
  end
171
194
 
172
195
  ##
173
- # Log template 'invalid object' message and return user-set object.
196
+ # Logs a new entry, if provided arguments are valid.
174
197
  #
175
- # @param id [String] invalid object identifier
176
- # @param mth [String] calling method identifier
177
- # @param ord [Integer] calling method argument order number of obj (optional)
178
- # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
179
- # @param res [Object] what to return (optional)
198
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL
199
+ # @param message [#to_s] user-provided log message
200
+ #
201
+ # @example A user warning
202
+ # log(WARN, "Surface area < 100cm2")
203
+ #
204
+ # @return [DEBUG, INFO, WARN, ERROR, FATAL] updated/current status
205
+ def log(lvl = DEBUG, message = "")
206
+ return @@status unless lvl.respond_to?(:to_i)
207
+ return @@status unless message.respond_to?(:to_s)
208
+
209
+ lvl = lvl.to_i
210
+ message = message.to_s
211
+ return @@status if lvl < DEBUG
212
+ return @@status if lvl > FATAL
213
+ return @@status if lvl < @@level
214
+
215
+ @@logs << {level: lvl, message: message}
216
+ return @@status unless lvl > @@status
217
+
218
+ @@status = lvl
219
+ end
220
+
221
+ ##
222
+ # Logs template 'invalid object' message, if provided arguments are valid.
180
223
  #
181
- # @return [Object] return object if specified by user
182
- # @return [Nil] nil if return object undefined
224
+ # @param id [#to_s] 'invalid object' identifier
225
+ # @param mth [#to_s] calling method identifier
226
+ # @param ord [#to_i] calling method argument order number of obj (optional)
227
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional)
228
+ # @param res what to return (optional)
229
+ #
230
+ # @example An invalid argument, logging a FATAL error, returning FALSE
231
+ # return invalid("area", "sum", 0, FATAL, false) if area > 1000000
232
+ #
233
+ # @return user-provided object
234
+ # @return [nil] if user hasn't provided an object to return
183
235
  def invalid(id = "", mth = "", ord = 0, lvl = DEBUG, res = nil)
184
236
  return res unless id.respond_to?(:to_s)
185
237
  return res unless mth.respond_to?(:to_s)
186
238
  return res unless ord.respond_to?(:to_i)
187
239
  return res unless lvl.respond_to?(:to_i)
188
240
 
189
- id = id.to_s.strip
190
- mth = mth.to_s.strip
191
241
  ord = ord.to_i
192
242
  lvl = lvl.to_i
193
-
194
- id = id[0...60] + " ..." if id.length > 60
243
+ id = trim(id)
244
+ mth = trim(mth)
195
245
  return res if id.empty?
196
-
197
- mth = mth[0...60] + " ..." if mth.length > 60
198
246
  return res if mth.empty?
247
+ return res if lvl < DEBUG
248
+ return res if lvl > FATAL
199
249
 
200
250
  msg = "Invalid '#{id}' "
201
251
  msg += "arg ##{ord} " if ord > 0
202
252
  msg += "(#{mth})"
203
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
253
+ log(lvl, msg)
204
254
 
205
255
  res
206
256
  end
207
257
 
208
258
  ##
209
- # Log template 'instance/class mismatch' message and return user-set object.
259
+ # Logs template 'instance/class mismatch' message, if provided arguments are
260
+ # valid. The message is not logged if the provided object to evaluate is an
261
+ # actual instance of the target class.
210
262
  #
211
- # @param id [String] mismatched object identifier
212
- # @param obj [Object] object to validate
263
+ # @param id [#to_s] mismatched object identifier
264
+ # @param obj the object to validate
213
265
  # @param cl [Class] target class
214
- # @param mth [String] calling method identifier
215
- # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
216
- # @param res [Object] what to return (optional)
266
+ # @param mth [#to_s] calling method identifier (optional)
267
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional)
268
+ # @param res what to return (optional)
217
269
  #
218
- # @return [Object] return object if specified by user
219
- # @return [Nil] nil if return object undefined
270
+ # @example A mismatched argument instance/class
271
+ # mismatch("area", area, Float, "sum") unless area.is_a?(Numeric)
272
+ #
273
+ # @return user-provided object
274
+ # @return [nil] if user hasn't provided an object to return
220
275
  def mismatch(id = "", obj = nil, cl = nil, mth = "", lvl = DEBUG, res = nil)
221
276
  return res unless id.respond_to?(:to_s)
277
+ return res unless mth.respond_to?(:to_s)
222
278
  return res unless cl.is_a?(Class)
223
279
  return res if obj.is_a?(cl)
224
- return res unless mth.respond_to?(:to_s)
225
280
  return res unless lvl.respond_to?(:to_i)
226
281
 
227
- mth = mth.to_s.strip
228
- id = id.to_s.strip
229
282
  lvl = lvl.to_i
230
-
231
- id = id[0...60] + " ..." if id.length > 60
283
+ id = trim(id)
284
+ mth = trim(mth)
232
285
  return res if id.empty?
233
-
234
- mth = mth[0...60] + " ..." if mth.length > 60
235
286
  return res if mth.empty?
287
+ return res if lvl < DEBUG
288
+ return res if lvl > FATAL
236
289
 
237
- msg = "'#{id}' #{obj.class}? expecting #{cl} (#{mth})"
238
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
290
+ log(lvl, "'#{id}' #{obj.class}? expecting #{cl} (#{mth})")
239
291
 
240
292
  res
241
293
  end
242
294
 
243
295
  ##
244
- # Log template 'missing hash key' message and return user-set object.
296
+ # Logs template 'missing hash key' message, if provided arguments are valid.
297
+ # The message is not logged if the provided key exists.
245
298
  #
246
- # @param id [String] Hash identifier
299
+ # @param id [#to_s] Hash identifier
247
300
  # @param hsh [Hash] hash to validate
248
- # @param key [Object] missing key
249
- # @param mth [String] calling method identifier
250
- # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
251
- # @param res [Object] what to return (optional)
301
+ # @param key missing key
302
+ # @param mth [#to_s] calling method identifier
303
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional)
304
+ # @param res what to return (optional)
305
+ #
306
+ # @example A missing Hash key
307
+ # hashkey("floor area", floor, :area, "sum") unless floor.key?(:area)
252
308
  #
253
- # @return [Object] return object if specified by user
254
- # @return [Nil] nil if return object undefined
309
+ # @return user-provided object
310
+ # @return [nil] if user hasn't provided an object to return
255
311
  def hashkey(id = "", hsh = {}, key = "", mth = "", lvl = DEBUG, res = nil)
256
312
  return res unless id.respond_to?(:to_s)
257
313
  return res unless hsh.is_a?(Hash)
@@ -259,121 +315,117 @@ module OSlg
259
315
  return res unless mth.respond_to?(:to_s)
260
316
  return res unless lvl.respond_to?(:to_i)
261
317
 
262
- id = id.to_s.strip
263
- mth = mth.to_s.strip
264
318
  lvl = lvl.to_i
265
-
266
- id = id[0...60] + " ..." if id.length > 60
319
+ id = trim(id)
320
+ mth = trim(mth)
267
321
  return res if id.empty?
268
-
269
- mth = mth[0...60] + " ..." if mth.length > 60
270
322
  return res if mth.empty?
323
+ return res if lvl < DEBUG
324
+ return res if lvl > FATAL
271
325
 
272
- msg = "Missing '#{key}' key in '#{id}' Hash (#{mth})"
273
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
326
+ log(lvl, "Missing '#{key}' key in '#{id}' Hash (#{mth})")
274
327
 
275
328
  res
276
329
  end
277
330
 
278
331
  ##
279
- # Log template 'empty (uninitialized)' message and return user-set object.
332
+ # Logs template 'empty' message, if provided arguments are valid.
280
333
  #
281
- # @param id [String] empty object identifier
282
- # @param mth [String] calling method identifier
283
- # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
284
- # @param res [Object] what to return (optional)
334
+ # @param id [#to_s] empty object identifier
335
+ # @param mth [#to_s] calling method identifier
336
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional)
337
+ # @param res what to return (optional)
285
338
  #
286
- # @return [Object] return object if specified by user
287
- # @return [Nil] nil if return object undefined
339
+ # @example An uninitialized variable, logging an ERROR, returning FALSE
340
+ # empty("zone", "conditioned?", FATAL, false) if space.thermalZone.empty?
341
+ #
342
+ # @return user-provided object
343
+ # @return [nil] if user hasn't provided an object to return
288
344
  def empty(id = "", mth = "", lvl = DEBUG, res = nil)
289
345
  return res unless id.respond_to?(:to_s)
290
346
  return res unless mth.respond_to?(:to_s)
291
347
  return res unless lvl.respond_to?(:to_i)
292
348
 
293
- id = id.to_s.strip
294
- mth = mth.to_s.strip
295
349
  lvl = lvl.to_i
296
-
297
- id = id[0...60] + " ..." if id.length > 60
350
+ id = trim(id)
351
+ mth = trim(mth)
298
352
  return res if id.empty?
299
-
300
- mth = mth[0...60] + " ..." if mth.length > 60
301
353
  return res if mth.empty?
354
+ return res if lvl < DEBUG
355
+ return res if lvl > FATAL
302
356
 
303
- msg = "Empty '#{id}' (#{mth})"
304
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
357
+ log(lvl, "Empty '#{id}' (#{mth})")
305
358
 
306
359
  res
307
360
  end
308
361
 
309
362
  ##
310
- # Log template 'near zero' message and return user-set object.
363
+ # Logs template 'zero' value message, if provided arguments are valid.
311
364
  #
312
- # @param id [String] zero object identifier
313
- # @param mth [String] calling method identifier
314
- # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
315
- # @param res [Object] what to return (optional)
365
+ # @param id [#to_s] zero object identifier
366
+ # @param mth [#to_s] calling method identifier
367
+ # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional)
368
+ # @param res what to return (optional)
369
+ #
370
+ # @example A near-zero variable
371
+ # zero("floor area", "sum") if floor[:area].abs < TOL
316
372
  #
317
- # @return [Object] return object if specified by user
318
- # @return [Nil] nil if return object undefined
373
+ # @return user-provided object
374
+ # @return [nil] if user hasn't provided an object to return
319
375
  def zero(id = "", mth = "", lvl = DEBUG, res = nil)
320
376
  return res unless id.respond_to?(:to_s)
321
377
  return res unless mth.respond_to?(:to_s)
322
378
  return res unless lvl.respond_to?(:to_i)
323
379
 
324
- id = id.to_s.strip
325
- mth = mth.to_s.strip
326
380
  ord = ord.to_i
327
381
  lvl = lvl.to_i
328
-
329
- id = id[0...60] + " ..." if id.length > 60
382
+ id = trim(id)
383
+ mth = trim(mth)
330
384
  return res if id.empty?
331
-
332
- mth = mth[0...60] + " ..." if mth.length > 60
333
385
  return res if mth.empty?
386
+ return res if lvl < DEBUG
387
+ return res if lvl > FATAL
334
388
 
335
- msg = "Zero '#{id}' (#{mth})"
336
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
389
+ log(lvl, "Zero '#{id}' (#{mth})")
337
390
 
338
391
  res
339
392
  end
340
393
 
341
394
  ##
342
- # Log template 'negative' message and return user-set object.
395
+ # Logs template 'negative' message, if provided arguments are valid.
343
396
  #
344
- # @param id [String] negative object identifier
397
+ # @param id [#to_s] negative object identifier
345
398
  # @param mth [String] calling method identifier
346
399
  # @param lvl [Integer] DEBUG, INFO, WARN, ERROR or FATAL (optional)
347
400
  # @param res [Object] what to return (optional)
348
401
  #
349
- # @return [Object] return object if specified by user
350
- # @return [Nil] nil if return object undefined
402
+ # @example A negative variable
403
+ # negative("floor area", "sum") if floor[:area] < 0
404
+ #
405
+ # @return user-provided object
406
+ # @return [nil] if user hasn't provided an object to return
351
407
  def negative(id = "", mth = "", lvl = DEBUG, res = nil)
352
408
  return res unless id.respond_to?(:to_s)
353
409
  return res unless mth.respond_to?(:to_s)
354
410
  return res unless lvl.respond_to?(:to_i)
355
411
 
356
- id = id.to_s.strip
357
- mth = mth.to_s.strip
358
- ord = ord.to_i
359
412
  lvl = lvl.to_i
360
-
361
- id = id[0...60] + " ..." if id.length > 60
413
+ id = trim(id)
414
+ mth = trim(mth)
362
415
  return res if id.empty?
363
-
364
- mth = mth[0...60] + " ..." if mth.length > 60
365
416
  return res if mth.empty?
417
+ return res if lvl < DEBUG
418
+ return res if lvl > FATAL
366
419
 
367
- msg = "Negative '#{id}' (#{mth})"
368
- log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
420
+ log(lvl, "Negative '#{id}' (#{mth})")
369
421
 
370
422
  res
371
423
  end
372
424
 
373
425
  ##
374
- # Reset log status and entries.
426
+ # Resets log status and entries.
375
427
  #
376
- # @return [Integer] current level
428
+ # @return [Integer] current log level
377
429
  def clean!
378
430
  @@status = 0
379
431
  @@logs = []
data/lib/oslg/version.rb CHANGED
@@ -29,5 +29,5 @@
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
31
  module OSlg
32
- VERSION = "0.2.7".freeze
32
+ VERSION = "0.2.9".freeze # OSlg version
33
33
  end
data/oslg.gemspec CHANGED
@@ -15,8 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.version = OSlg::VERSION
16
16
  s.license = "BSD-3-Clause"
17
17
  s.summary = "OpenStudio SDK logger"
18
- s.description = "For OpenStudio SDK users who wish to select " \
19
- "what gets logged to which target."
18
+ s.description = "For OpenStudio SDK users (or others) who wish "\
19
+ "to select what gets logged to which target."
20
20
  s.authors = ["Denis Bourgeois"]
21
21
  s.email = ["denis@rd2.ca"]
22
22
  s.platform = Gem::Platform::RUBY
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oslg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Bourgeois
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-07 00:00:00.000000000 Z
11
+ date: 2023-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,8 +52,8 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.11'
55
- description: For OpenStudio SDK users who wish to select what gets logged to which
56
- target.
55
+ description: For OpenStudio SDK users (or others) who wish to select what gets logged
56
+ to which target.
57
57
  email:
58
58
  - denis@rd2.ca
59
59
  executables: []
@@ -76,7 +76,7 @@ licenses:
76
76
  - BSD-3-Clause
77
77
  metadata:
78
78
  homepage_uri: https://github.com/rd2/oslg
79
- source_code_uri: https://github.com/rd2/oslg/tree/v0.2.7
79
+ source_code_uri: https://github.com/rd2/oslg/tree/v0.2.9
80
80
  bug_tracker_uri: https://github.com/rd2/oslg/issues
81
81
  post_install_message:
82
82
  rdoc_options: []