Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(semconv): Add a field note to the deprecated struct. #602

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

lquerel
Copy link
Contributor

@lquerel lquerel commented Feb 13, 2025

Added a note field to all deprecated variants.
In Jinja, deprecated | string now outputs the content of the deprecated.note field.

The content of the field deprecated.note depends on the nature of the deprecated field.

  • For a deprecated field of type string, the generated deprecated.note field contains the text value of the deprecated field.
  • For a structured deprecated field, the value of the deprecated.note field is used.

@lquerel lquerel requested a review from a team as a code owner February 13, 2025 00:31
@lquerel lquerel self-assigned this Feb 13, 2025
@lquerel lquerel added the bug Something isn't working label Feb 13, 2025
@lquerel lquerel requested review from jsuereth and lmolkova February 13, 2025 00:33
} => {
changes.add_change(
SchemaItemType::RegistryAttributes,
SchemaItemChange::Renamed {
old_name: baseline_attr.name.clone(),
new_name: rename_to.clone(),
note: attr.brief.clone(),
note: note.clone().unwrap_or_else(|| attr.brief.clone()),
Copy link
Contributor

@lmolkova lmolkova Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to fall back to the attribute brief if we have a note.

For existing versions of semconv, we just need to use deprecated string value.

For new conventions we only have a need it for uncategorized changes. We should generate the rest

{% macro deprecated_note(attribute) %}
{% if attribute.deprecated.reason == "renamed" %}
    {{ "Replaced by `" ~ attribute.deprecated.renamed_to | trim ~ "`." }}
{% elif attribute.deprecated.reason == "obsoleted" %}
    {{ "Removed." }}
{% else %}
    {{ attribute.brief }}
{% endif %}
{% endmacro %}

If we end up adding an optional note everywhere, we still want a default note to be generated (let's not ask everyone to write jinja for it).

E.g. we'd do

{% macro deprecated_note(attribute) %}
{% if attribute.deprecated.note %}
    {{ attribute.deprecated.note }}
{% else %}
    {% if attribute.deprecated.reason == "renamed" %}
      {{ "Replaced by `" ~ attribute.deprecated.renamed_to | trim ~ "`." }}
    {% elif attribute.deprecated.reason == "obsoleted" %}
      {{ "Removed." }}
    {% else %}
      {{ attribute.deprecated.note }}
    {% endif %}
{% endif %}
{% endmacro %}

So, if you'd prefer to add note for all change types, the suggestion is:

  • do not fall back to the attribute brief
  • if note is not provided, create a default one following the pattern above. We'd need to define a default note format for each future transformation

I.e. the codegen/semconv md would be able to do something like this:

{% if attribute is deprecated %}
  {{ attribute.deprecated.note}}
{% endif %}

E.g. for otel-rust, the immediate change would be

-#[deprecated(note="{{ attr.deprecated.strip(" \n\"") }}")]
+#[deprecated(note="{{ attr.deprecated.note.strip(" \n\"") }}")]

(and they can always customize the default by exploring attr.deprecated)

Copy link
Contributor Author

@lquerel lquerel Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to fall back to the attribute brief if we have a note.

I'm not. I only fall back to thebrief field if there is no note.
Now if you prefer, I can remove the entire fall back mechanism even when there is no deprecated.note. I'm waiting for your feedback on this before to make any change.

For new conventions we only have a need it for uncategorized changes. We should generate the rest

I might have misinterpreted the example you gave in the Slack channel, but I think your example demonstrated the opposite. You requested a note for something that wasn’t uncategorized but rather renamed. Based on this example, it seems like we need to support note for more than just uncategorized changes. Did I miss something?

Copy link
Contributor

@lmolkova lmolkova Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want us to format a note if it was not provided.

  • For renamed it would be f"Renamed to {renamed_to}"
  • For obsoleted it would be Removed (or Obsoleted)
  • For uncategorized it would be Removed

I.e. resolved deprecated.note would come from (in the priority it's listed)

  1. original string value of deprecated property if it was provided
  2. deprecated.note if it was provided explicitly
  3. from the above formatting rules

This way 1) existing semconv and codegen would keep working as is. 2) once we start updating to new deprecation syntax, we won't have to write notes on everything 3) we could keep the original attribute briefs if necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing code behaves as follows:

  • If the semconv file contains a deprecated field with a string value, it is automatically converted into:
deprecated:your 
  reason: uncategorized
  note: <string value found in the semconv file>
  • If the semconv file contains a structured deprecated field and the predicated.note field is defined then we keep it.
  • If the semconv file contains a structured deprecated field and the note sub-field is not defined, this field is initialized with the content of the attribute/signal brief field.
  • When the deprecated.note field is used in a Jinja template, it will always contain one of the two values described above.
  • When a template references deprecated without the deprecated | string filter, Jinja renders the struct itself and does not call the struct’s to_string Rust method. As mentioned in the initial release, this introduces a breaking change for templates but does not affect the semconv files themselves (we support the two formats for them).
  • When a template calls deprecated | string, the Deprecated::to_string() Rust method is invoked, and the deprecated.note field is used (which should never be empty, as we fall back to brief if necessary).

What you’re describing is a bit different. You don’t want to fall back to the brief field when deprecated.note is missing from the initial semconv file. Instead, you prefer generating a note using one of the patterns specified in your first list (e.g., “Renamed to {renamed_to}”). That works for me, but it’s important to note that there is still a breaking change for existing templates.

When Jinja encounters a struct in a placeholder without a filter, it simply tries to render the struct’s content instead of calling its to_string method. I’m not sure whether this is a limitation of the minijinja engine we’re using or just the expected behavior of Jinja (which wouldn’t surprise me).

So, I’ll make the modification you proposed, and I hope these additional details clarify that a breaking change still remains for the template authors.

Copy link
Contributor

@jerbly jerbly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new note field needs to go in the json schema:

"Deprecated": {
and the syntax doc:
deprecated ::= renamed

@lquerel lquerel requested a review from a team as a code owner February 13, 2025 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Next Release
Development

Successfully merging this pull request may close these issues.

3 participants