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 +4 -4
- data/.github/workflows/pull_request.yml +1 -81
- data/README.md +35 -37
- data/lib/oslg/oslog.rb +213 -161
- data/lib/oslg/version.rb +1 -1
- data/oslg.gemspec +2 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6af1c266df1a21c24e1f810ae3a13ea4b8cee514ef522860f67c94e0108faca
|
4
|
+
data.tar.gz: ecc6bdccad1d9e3de77eb27f17e9d63b82aa290f982dd3a525f786de576341d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 107bf656388646393a97f60a3a49ddaf3f23764c4f8f91445d131813ec33c53c699a7f25f2e6f90058f23faa93eeb1d5abdeb48f6260ae36f99402a4ab91b4cd
|
7
|
+
data.tar.gz: 5a4bd5a3de4d1d0e96c274e31c63cdee2fec3adc470c88881225ebc475d8b91362585766197dd37110565f7480792bfd2523423bba6847158e2c16ad54bb5e05
|
@@ -6,87 +6,7 @@ on:
|
|
6
6
|
- dev
|
7
7
|
|
8
8
|
jobs:
|
9
|
-
|
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
|
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)
|
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)
|
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
|
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
|
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
|
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
|
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
|
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__),
|
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.
|
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::
|
115
|
+
return M.invalid("area", "sum", 0, M::FATAL, false) if area > 1000000
|
116
116
|
```
|
117
117
|
|
118
|
-
This logs
|
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
|
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
|
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("
|
147
|
+
return M.mismatch("area", area, Float, "sum") unless area.is_a?(Numeric)
|
148
148
|
```
|
149
149
|
|
150
|
-
If '
|
150
|
+
If 'area' were for example a _String_, __mismatch__ would generate the following DEBUG log message (before returning _nil_):
|
151
151
|
|
152
152
|
```
|
153
|
-
"'
|
153
|
+
"'area' String? expecting Float (sum)"
|
154
154
|
```
|
155
155
|
|
156
|
-
These
|
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("
|
163
|
+
return M.hashkey("floor area", floor, :area, "sum") unless floor.key?(:area)
|
164
164
|
```
|
165
165
|
|
166
|
-
If the _Hash_ `
|
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 '
|
169
|
+
"Missing 'area' key in 'floor' Hash (sum)"
|
170
170
|
```
|
171
171
|
|
172
|
-
Similar to __mismatch__, the method __hashkey__ requires
|
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
|
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("
|
179
|
+
return M.empty("zone", "conditioned?", M::FATAL, false) if space.thermalZone.empty?
|
180
180
|
```
|
181
181
|
|
182
|
-
An empty `
|
182
|
+
An empty (i.e. uninitialized) `thermalZone` would generate the following FATAL error log message (before returning _false_):
|
183
183
|
|
184
184
|
```
|
185
|
-
"Empty '
|
185
|
+
"Empty 'zone' (conditioned?)"
|
186
186
|
```
|
187
187
|
|
188
|
-
Again, the first
|
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.
|
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
|
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
|
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
|
33
|
-
INFO
|
34
|
-
WARN
|
35
|
-
ERROR
|
36
|
-
FATAL
|
37
|
-
|
38
|
-
|
39
|
-
@@
|
40
|
-
|
41
|
-
|
42
|
-
@@tag
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@@msg
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
#
|
65
|
+
# Returns log entries.
|
60
66
|
#
|
61
|
-
# @return [Array]
|
67
|
+
# @return [Array<Hash>] log entries (see @@logs)
|
62
68
|
def logs
|
63
69
|
@@logs
|
64
70
|
end
|
65
71
|
|
66
72
|
##
|
67
|
-
#
|
73
|
+
# Returns current log level.
|
68
74
|
#
|
69
|
-
# @return [
|
75
|
+
# @return [DEBUG, INFO, WARN, ERROR, FATAL] log level
|
70
76
|
def level
|
71
77
|
@@level
|
72
78
|
end
|
73
79
|
|
74
80
|
##
|
75
|
-
#
|
81
|
+
# Returns current log status.
|
76
82
|
#
|
77
|
-
# @return [
|
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
|
-
#
|
89
|
+
# Returns whether current status is DEBUG.
|
84
90
|
#
|
85
|
-
# @return [Bool]
|
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
|
-
#
|
97
|
+
# Returns whether current status is INFO.
|
92
98
|
#
|
93
|
-
# @return [Bool]
|
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
|
-
#
|
105
|
+
# Returns whether current status is WARN.
|
100
106
|
#
|
101
|
-
# @return [Bool]
|
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
|
-
#
|
113
|
+
# Returns whether current status is ERROR.
|
108
114
|
#
|
109
|
-
# @return [Bool]
|
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
|
-
#
|
121
|
+
# Returns whether current status is FATAL.
|
116
122
|
#
|
117
|
-
# @return [Bool]
|
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
|
-
#
|
129
|
+
# Returns preset OSlg string that matches log level.
|
124
130
|
#
|
125
|
-
# @param
|
131
|
+
# @param lvl [#to_i] 0, DEBUG, INFO, WARN, ERROR or FATAL
|
126
132
|
#
|
127
|
-
# @return [String]
|
128
|
-
def tag(
|
129
|
-
return
|
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
|
-
#
|
146
|
+
# Returns preset OSlg message that matches log status.
|
136
147
|
#
|
137
|
-
# @param
|
148
|
+
# @param stat [Integer] 0, DEBUG, INFO, WARN, ERROR or FATAL
|
138
149
|
#
|
139
|
-
# @return [String] preset OSlg message
|
140
|
-
def msg(
|
141
|
-
return
|
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
|
-
#
|
162
|
+
# Converts object to String and trims if necessary.
|
148
163
|
#
|
149
|
-
# @param
|
164
|
+
# @param txt [#to_s] a stringable object
|
165
|
+
# @param length [#to_i] maximum return string length
|
150
166
|
#
|
151
|
-
# @return [
|
152
|
-
def
|
153
|
-
|
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
|
-
#
|
180
|
+
# Resets level, if lvl (input) is within accepted range.
|
158
181
|
#
|
159
|
-
# @param
|
160
|
-
# @param message [String] user-provided message
|
182
|
+
# @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL
|
161
183
|
#
|
162
|
-
# @return [
|
163
|
-
def
|
164
|
-
|
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
|
-
|
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
|
-
#
|
196
|
+
# Logs a new entry, if provided arguments are valid.
|
174
197
|
#
|
175
|
-
# @param
|
176
|
-
# @param
|
177
|
-
#
|
178
|
-
# @
|
179
|
-
#
|
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
|
-
# @
|
182
|
-
# @
|
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
|
-
|
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)
|
253
|
+
log(lvl, msg)
|
204
254
|
|
205
255
|
res
|
206
256
|
end
|
207
257
|
|
208
258
|
##
|
209
|
-
#
|
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 [
|
212
|
-
# @param obj
|
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 [
|
215
|
-
# @param lvl [
|
216
|
-
# @param res
|
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
|
-
# @
|
219
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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 [
|
299
|
+
# @param id [#to_s] Hash identifier
|
247
300
|
# @param hsh [Hash] hash to validate
|
248
|
-
# @param key
|
249
|
-
# @param mth [
|
250
|
-
# @param lvl [
|
251
|
-
# @param res
|
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
|
254
|
-
# @return [
|
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
|
-
|
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
|
-
|
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
|
-
#
|
332
|
+
# Logs template 'empty' message, if provided arguments are valid.
|
280
333
|
#
|
281
|
-
# @param id [
|
282
|
-
# @param mth [
|
283
|
-
# @param lvl [
|
284
|
-
# @param res
|
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
|
-
# @
|
287
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
#
|
363
|
+
# Logs template 'zero' value message, if provided arguments are valid.
|
311
364
|
#
|
312
|
-
# @param id [
|
313
|
-
# @param mth [
|
314
|
-
# @param lvl [
|
315
|
-
# @param res
|
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
|
318
|
-
# @return [
|
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
|
-
|
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
|
-
|
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
|
-
#
|
395
|
+
# Logs template 'negative' message, if provided arguments are valid.
|
343
396
|
#
|
344
|
-
# @param id [
|
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
|
-
# @
|
350
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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
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
|
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.
|
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-
|
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
|
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.
|
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: []
|