-
Notifications
You must be signed in to change notification settings - Fork 475
Log functionAppVersion during initialization #11527
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
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds logging for the system version during host initialization to support tracking rolling updates. The system version is a UUIDv7 derived from configuration and deployment timestamps.
Key changes:
- Added
SYSTEM_VERSIONenvironment variable support throughout the codebase - Implemented logging of system version during host initialization
- Added system version handling in host assignment context for specialization scenarios
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/WebJobs.Script/Environment/EnvironmentSettingNames.cs | Added constant for SYSTEM_VERSION environment variable |
| src/WebJobs.Script/Environment/EnvironmentExtensions.cs | Added extension method to retrieve system version from environment |
| src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs | Added logging call for system version during initialization |
| src/WebJobs.Script.WebHost/Models/HostAssignmentContext.cs | Added SystemVersion property and logic to set it as environment variable |
| src/WebJobs.Script.WebHost/Diagnostics/Extensions/ScriptHostServiceLoggerExtension.cs | Added logger extension method for system version logging |
958bc68 to
4b7eebb
Compare
|
Can you expand on what |
|
Thank you for your response @jviau |
| LoggerMessage.Define<string>( | ||
| LogLevel.Information, | ||
| new EventId(532, nameof(LogSystemVersion)), | ||
| "Host is running on version '{systemVersion}'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'systemVersion' is not the host runtime version. We have to rephrase the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we talk about if we could have this in its own ColumnName or just in the Message to avoid having to parse the FunctionsLogs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'systemVersion' is not the host runtime version. We have to rephrase the message.
@RohitRanjanMS I updated the message. @FinVamp1, @im-samz can you confirm if this logging message looks good to you or if you have suggestions for the message?
Did we talk about if we could have this in its own ColumnName or just in the Message to avoid having to parse the FunctionsLogs?
@FinVamp1 Since this is meant to be a log (instead of a column in the logs), users will have to search for this specific message and then parse it in the logs. But aside from the log changes in this PR, Rohit will do separate work to have it be its own column in the requests table (potentially under customDimensions), and this will not require having to search and parse a specific message. To provide you more context on why we decided to go with this approach, we discussed that adding it as a column for all logs means additional cost for storage to keep this telemetry. So instead, we will only have this single log when the instance is initialized, and it will also be a dimension for the requests table since requests is another critical area where we think customers will want to see the version. TLDR: instead of adding it as it as a column for all logs, we have agreed on the critical areas where customers would want to see this information.
4b7eebb to
b3f3209
Compare
|
Yeah, not sure I like I like |
|
Another question: will this ID also incorporate host version? As in, a new ID will be used when host version is updated. I could see this going either way. |
b3f3209 to
08b7fad
Compare
These are good suggestions. Thank you @jviau. I've passed them along to Sam so he can weigh in on which option will best fit customers' expectations (for context, this will also become a column name in the requests table in App Insights, potentially under customDimensions).
It is not meant to be updated when the host version is updated. It is just meant to track the site_config+code_content that the instance is running on. So, unless the customer updated the app's site configs or deployed to the app, this value will remain the same even after a host version update. |
Let's use |
Kudu already has a deploymentId property which is a GUID for each unique deployment. Do we risk overloading the term? |
|
@FinVamp1 do you have some docs on the Kudu deployment ID? How is it exposed to customers today, if at all? Can that Kudu deployment ID be updated to use the same value as this PR for Flex apps? If we can unify these two IDs that would be awesome. |
Thanks @jviau the deploymentId isn't a GUID after all but a string. I know code isn't documentation but here's a sense of how it works. This deployment ID gets exposed to customers in a number of places.
This version value related to this PR is for both code and site config changes whereas the deploymentId has historically only been for code changes. So it might be considered a breaking change to re-purpose it here. |
|
ACK'ing on this thread. I'm still reasoning over the names for our platform-managed and user-defined versions. The deployment commitments we have in 2026 all require customers to reason about the state of an app over time, so the vocabulary decisions we make will either make the deployment story feel coherent or permanently confusing. Thinking out loud here: "version" in Functions is already an overloaded term...Given that the two proposed "versions" serve different purposes, I wonder if we should escape the use of "versions" altogether. Imagine hitting CTRL-F for "version" in our learn docs that explain how to use rolling updates with rollbacks; reasoning about different types of versions with only an adjective differentiating them might be prone to misreading. My hunch so far is:
Other pairs:
|
Guid vs string isn't that big of a deal. GUIDs are often represented as strings.
How does this show up in these logs? Do you have an exact log example you can share? And does it show up in Flex sku specifically? |
|
Another point on the site config changes influencing this value: will this detect changes when a config value is pulled in via key vault or azure app config? |
Is there something specific you want to know about the Id? I have outlined examples below. For Flex we log the Deployment details to ApplicationInsights if it is configured.
For Azure DevOps here's an example of where it is seen
with additional information if you have deployed with the DevOps Debug Flag turned on.
For DevOps we will also look the deployment logs to Application Insights if the resource that we deploy to has it enabled. For Linux Dedicated the Kudu logs look like this.
In the Linux Dedicated NewUI it looks like this
For Flex with OneDeploy you would see something like this Run Azure Functions Action From the CLI you can get the Deployment list and ID's List all deployment records for a Function Appaz functionapp log deployment list Show logs for the latest deployment (or a specific one by ID)az functionapp log deployment show For Windows Dedicated here's how it looks in Deployment Center
And in Kudu
And in the Kudu File System
Windows Consumption looks the same as dedicated.
So the Kudu Logs will look the same for Windows Consumption. Linux Consumption doesn't have a Kudu instance that persists but the deploymentId is still logged. |
|
Thank you for your input @im-samz @FinVamp1 @jviau What do you think of using
Whenever the siteLastModifiedTime is updated, we will update the site config timestamp that backs this value. My understanding is that if the customer updates that value in key vault or azure app config, we do not update siteLastModifiedTime on our end since we are just pulling the updated value from the same source that was previously configured. Is that correct? If so, then to answer your question, we would not detect changes from updating values in key vault or azure app config. But I would say that this is the intended behavior since we are only trying to track the updates made to the Site resource that cause your instances to be recycled. |
|
After @RohitRanjanMS shared that OTel link, I saw that I do really like |
Deployment is already an overloaded term in terms of Functions Deployment. Customers use it interchangeably to mean app create/delete, code deployment , site configuration changes and also v1 to v2 even if it's a new app. So hopefully we are in agreement that using deploymentId is out of scope for this discussion. |
|
To keep this thread updated, @im-samz is still deciding if we can use |
|
Hey team! I'm learning towards OTel has an attribute faas.version; the equivalent in Lambda is version and in GCP it's revision. Both of these are immutable snapshots of an app that can be audited and routed traffic to. What we're introducing here isn't equivalent either to Lamba's versions or GCP's revisions; what we have here is just a unique identifier. Hence, I want to avoid the term "revision" or "version" since those terms already have connotations in the industry. In fact, I want to avoid introducing another concept at all. Moreover, we are introducing a user-defined version, so I want to reserve both the term and the OTel attribute for it: For this reason, I'm now learning towards For a sanity check, this is essentially what we'd say in our documentation without the terms:
This is what it would look like when using our terms:
|
| LoggerMessage.Define<string>( | ||
| LogLevel.Information, | ||
| new EventId(532, nameof(LogFunctionAppVersion)), | ||
| "Running following version from app configuration update or code content deployment: '{functionAppVersion}'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "Running following version from app configuration update or code content deployment: '{functionAppVersion}'."); | |
| "Running app with code and config state '{functionAppVersion}'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Framing this field less like a "version" and more like an "identifier".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do worry that using terms like config state is a bit misleading. Customers may have more config state than what we are including in the calculation here.
Will this identifier detect changes to app settings? How about when app settings point to a key vault or azure app config, will this know when those dereferenced values change?
Also, will customers assume this is the complete config state for their own worker process? Because it isn't, they can be loading config state from wherever, it's a black box to us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is structured logging, functionAppVersion will be recorded as a custom dimension. We need both a clear log message and the attribute name. How about deployment.id but scoping it to Azure Functions, for example azure.functions.deployment.id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we agree on appRevisionId or do we need to use deploymentId for Otel reasons?









Issue describing the changes in this PR
As part of the rolling updates feature, customers would like to track how their rolling update is progressing (i.e. how many v1 vs v2 instances they have up and running). In order to achieve this, we want to add a log during initialization that will indicate what version the worker is running on. In Legion, this systemVersion attribute is sent as a UUIDv7 from the MAX(configLastModifiedTime, contentLastModifiedTime) where configLastModifiedTime is the last timestamp when the site configuration was updated, and contentLastModifiedTime is the last timestamp when the code deployment was triggered for the app.
Pull request checklist
IMPORTANT: Currently, changes must be backported to the
in-procbranch to be included in Core Tools and non-Flex deployments.in-procbranch is not requiredrelease_notes.mdAdditional information
Additional PR information