Working solution serialization bug.#5874
Conversation
|
Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide. |
gshank
left a comment
There was a problem hiding this comment.
We're converting all of these Exception object to strings in the next structured logging update anyway, because everything in the event has to be encoded into a protobuf message.
|
So it looks like #5385 has the exact same problem (passing a non-string to |
…utes. Before this change, the spec of various classes expected base_msg and msg params to be str's. This assumption did not always hold true. post_init hooks ensures the spec is obeyed.
e07829f to
ef4eae9
Compare
|
Revised in light of the recent structured logging change. PR description revised, mostly expanded to describe the second bug. Employs the same subclass-as-trait paradigm to . And for good measure, I did check the new structured logging code on main still exhibits the bugs described in the linked issues before folding these changes into the code. |
7e59699 to
2dae7e7
Compare
| class AdapterEventStringFunctor: | ||
| def __post_init__(self): | ||
| super().__post_init__() | ||
| if not isinstance(self.base_msg, str): |
There was a problem hiding this comment.
do we need to check if base_msg exists?
There was a problem hiding this comment.
Thought about this. We're talking data classes so these objects must be instantiated with params. A little toy example:
from dataclasses import dataclass
@dataclass
class Item:
a:str
b:str
c:str
asdf = Item()Try running this and it complains:
TypeError: init() missing 3 required positional arguments: 'a', 'b', and 'c'
Hence, if a dataclass exists, it's gotta have the params. And this functor should only be used in classes that have this param. I think that renders an existential check redundant? (if it's not, tell me)
colin-rogers-dbt
left a comment
There was a problem hiding this comment.
Makes sense, just one question. Also, do we need unit tests to validate this behavior?
|
Unsure about unit tests. Is it worth having tests to check that the intended spec holds for something like the structured logging? That feels extra to me, but I'm also open to writing some quick ones if it seems like a good idea from your POV! |
resolves #5436
resolves #5385
Description
Ho, boy! What an odyssey. This PR has some reworks to the adapter logging functions for dbt. These changes help us conform to the intended spec of the logging classes. The resulting behavior makes our log functions reminiscent of python's
print().reproducing the errors
5385
models/asdf.sql:{% set some_list = ['a', 'b', 'c'] %} {{ log(some_list, info = true) }} select 1 as id5436
asdf2.sql:dbt --no-use-colors --log-format json run -s asdf2 | jq .msg——————
dbt-bigquery==1.0.0
dbt-core==1.0.8
dbt-bigquery==1.1.0
dbt-core==1.1.2
dbt-bigquery==1.2.0
dbt-bigquery==1.3.0b2
dbt-core==1.3.0b2
dbt-core==1.2.1
Error 1: Serialization Woes
json.dumpspresumes that all elements within a dictionary can be simply rendered as a json string. But complex objects inside the argument will cause a serialization error. This happens precisely at line 209 of core/dbt/events/functions.Several classes have
msgparameter. This spec does not always match reality: Some arguments are not strings. This leads to trouble whenloggermember function calls are made. So, if we force the message given to logger functions to be a string, the spec matches reality and the error vanishes. Local proof of it working on development.This error is what the user OwenKephart graciously documented over in Bigquery issue 206 as a desired output for my test case model, designed to fail.
QED.
Error 2: Secret scrubbing implodes when provided a non-str type
Jinja
loghands a type to Python which should but isn't always a string. Although, we have a functionscrub_secretswhich expects that.By making sure these
MacroEvent*types are all in fact strings, we solve the current problem and hopefully, future ones.Checklist
changie newto create a changelog entry