Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions src/Agent.Listener/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Microsoft.VisualStudio.Services.Agent.Listener.Telemetry;
using System.Collections.Generic;
using Newtonsoft.Json;
using Agent.Sdk.Knob;
using Agent.Listener.Configuration;

namespace Microsoft.VisualStudio.Services.Agent.Listener
Expand Down Expand Up @@ -354,12 +355,41 @@ private void CtrlCHandler(object sender, EventArgs e)
}
}

private async Task InitializeRuntimeFeatures()
{
try
{
Trace.Info("Initializing runtime features from feature flags");

var featureFlagProvider = HostContext.GetService<IFeatureFlagProvider>();
var traceManager = HostContext.GetService<ITraceManager>();

// Check enhanced logging feature flag
var enhancedLoggingFlag = await featureFlagProvider.GetFeatureFlagAsync(HostContext, "DistributedTask.Agent.UseEnhancedLogging", Trace);
bool enhancedLoggingEnabled = string.Equals(enhancedLoggingFlag?.EffectiveState, "On", StringComparison.OrdinalIgnoreCase);

Trace.Info($"Enhanced logging feature flag is {(enhancedLoggingEnabled ? "enabled" : "disabled")}");
// Set the result on TraceManager - this automatically switches all trace sources
traceManager.SetEnhancedLoggingEnabled(enhancedLoggingEnabled);

// Ensure child processes (worker/plugin) pick up enhanced logging via knob
Environment.SetEnvironmentVariable("AZP_USE_ENHANCED_LOGGING", enhancedLoggingEnabled ? "true" : null);

Trace.Info("Runtime features initialization completed successfully");
}
catch (Exception ex)
{
// Don't fail the agent if feature flag check fails
Trace.Warning($"Runtime features initialization failed, using defaults: {ex}");
}
}

//create worker manager, create message listener and start listening to the queue
private async Task<int> RunAsync(AgentSettings settings, bool runOnce = false)
{
try
{
Trace.Info($"Entering main agent execution loop({0})", nameof(RunAsync));
Trace.Info($"Entering main agent execution loop({nameof(RunAsync)})");

var featureFlagProvider = HostContext.GetService<IFeatureFlagProvider>();
var checkPsModulesFeatureFlag = await featureFlagProvider.GetFeatureFlagAsync(HostContext, "DistributedTask.Agent.CheckPsModulesLocations", Trace);
Expand All @@ -385,6 +415,10 @@ private async Task<int> RunAsync(AgentSettings settings, bool runOnce = false)

HostContext.WritePerfCounter("SessionCreated");
Trace.Info("Session created successfully - agent is now listening for jobs");

// Check feature flags for enhanced logging and other runtime features
await InitializeRuntimeFeatures();

_term.WriteLine(StringUtil.Loc("ListenForJobs", DateTime.UtcNow));

IJobDispatcher jobDispatcher = null;
Expand Down Expand Up @@ -513,7 +547,7 @@ private async Task<int> RunAsync(AgentSettings settings, bool runOnce = false)
var agentUpdateMessage = JsonUtility.FromString<AgentRefreshMessage>(message.Body);
var selfUpdater = HostContext.GetService<ISelfUpdater>();
selfUpdateTask = selfUpdater.SelfUpdate(agentUpdateMessage, jobDispatcher, !runOnce && HostContext.StartupType != StartupType.Service, HostContext.AgentShutdownToken);
Trace.Info("Agent update handling - Self-update task initiated, target version: {0}", agentUpdateMessage.TargetVersion);
Trace.Info($"Agent update handling - Self-update task initiated, target version: {agentUpdateMessage.TargetVersion}");
}
else
{
Expand Down Expand Up @@ -585,7 +619,7 @@ private async Task<int> RunAsync(AgentSettings settings, bool runOnce = false)
catch (AggregateException e)
{
Trace.Error($"Exception occurred while processing message from queue: {e.Message}");
ExceptionsUtil.HandleAggregateException((AggregateException)e, Trace.Error);
ExceptionsUtil.HandleAggregateException((AggregateException)e, (message) => Trace.Error(message));
}
finally
{
Expand Down
2 changes: 1 addition & 1 deletion src/Agent.Listener/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ public async Task ConfigureAsync(CommandSettings command)
}
catch (SocketException ex)
{
ExceptionsUtil.HandleSocketException(ex, agentSettings.ServerUrl, Trace.Error);
ExceptionsUtil.HandleSocketException(ex, agentSettings.ServerUrl, (message) => Trace.Error(message));
throw;
}

Expand Down
22 changes: 11 additions & 11 deletions src/Agent.Listener/Configuration/ConfigurationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public async Task<TaskAgent> GetAgentAsync(AgentSettings agentSettings)
{
ArgUtil.NotNull(agentSettings, nameof(agentSettings));
var agents = await _agentServer.GetAgentsAsync(agentSettings.PoolId, agentSettings.AgentName);
Trace.Verbose("Returns {0} agents", agents.Count);
Trace.Verbose($"Returns {agents.Count} agents");
return agents.FirstOrDefault();
}
}
Expand Down Expand Up @@ -233,7 +233,7 @@ public virtual async Task DeleteAgentAsync(AgentSettings agentSettings)
{
ArgUtil.NotNull(agentSettings, nameof(agentSettings));
var machines = await GetDeploymentTargetsAsync(agentSettings);
Trace.Verbose("Returns {0} machines with name {1}", machines.Count, agentSettings.AgentName);
Trace.Verbose($"Returns {machines.Count} machines with name {agentSettings.AgentName}");
var machine = machines.FirstOrDefault();
if (machine != null)
{
Expand Down Expand Up @@ -274,7 +274,7 @@ public virtual async Task<TaskAgent> GetAgentAsync(AgentSettings agentSettings)
{
ArgUtil.NotNull(agentSettings, nameof(agentSettings));
var machines = await GetDeploymentTargetsAsync(agentSettings);
Trace.Verbose("Returns {0} machines", machines.Count);
Trace.Verbose($"Returns {machines.Count} machines");
var machine = machines.FirstOrDefault();
if (machine != null)
{
Expand Down Expand Up @@ -372,7 +372,7 @@ private async Task<string> GetAzureSubscriptionIdAsync()
catch (SocketException ex)
{
azureSubscriptionId = string.Empty;
ExceptionsUtil.HandleSocketException(ex, imdsUri, Trace.Info);
ExceptionsUtil.HandleSocketException(ex, imdsUri, (message) => Trace.Info(message));
}
catch (Exception ex)
{
Expand Down Expand Up @@ -459,7 +459,7 @@ public override async Task GetPoolIdAndName(AgentSettings agentSettings, Command
agentSettings.EnvironmentId = environmentInstance.Id;
agentSettings.ProjectName = environmentInstance.Project.Name;
agentSettings.ProjectId = environmentInstance.Project.Id.ToString();
Trace.Info("vm resource configuration: environment id: '{0}', project name: '{1}', project id: '{2}'", agentSettings.EnvironmentId, agentSettings.ProjectName, agentSettings.ProjectId);
Trace.Info($"vm resource configuration: environment id: '{agentSettings.EnvironmentId}', project name: '{agentSettings.ProjectName}', project id: '{agentSettings.ProjectId}'");
}

public override string GetFailedToFindPoolErrorString() => StringUtil.Loc("FailedToFindEnvironment");
Expand All @@ -483,7 +483,7 @@ public override async Task<TaskAgent> AddAgentAsync(AgentSettings agentSettings,
Trace.Info("Environment virtual machine resource with name: '{0}', id: '{1}' has been added successfully.", virtualMachine.Name, virtualMachine.Id);

var pool = await _environmentsServer.GetEnvironmentPoolAsync(new Guid(agentSettings.ProjectId), agentSettings.EnvironmentId);
Trace.Info("environment pool id: '{0}'", pool.Id);
Trace.Info($"environment pool id: '{pool.Id}'");
agentSettings.PoolId = pool.Id;
agentSettings.AgentName = virtualMachine.Name;
agentSettings.EnvironmentVMResourceId = virtualMachine.Id;
Expand Down Expand Up @@ -517,7 +517,7 @@ private IList<String> GetVirtualMachineResourceTags(CommandSettings command)
public override async Task DeleteAgentAsync(AgentSettings agentSettings)
{
ArgUtil.NotNull(agentSettings, nameof(agentSettings));
Trace.Info("Deleting environment virtual machine resource with id: '{0}'", agentSettings.EnvironmentVMResourceId);
Trace.Info($"Deleting environment virtual machine resource with id: '{agentSettings.EnvironmentVMResourceId}'");
if (!string.IsNullOrWhiteSpace(agentSettings.ProjectId))
{
await _environmentsServer.DeleteEnvironmentVMAsync(new Guid(agentSettings.ProjectId), agentSettings.EnvironmentId, agentSettings.EnvironmentVMResourceId);
Expand All @@ -526,14 +526,14 @@ public override async Task DeleteAgentAsync(AgentSettings agentSettings)
{
await _environmentsServer.DeleteEnvironmentVMAsync(agentSettings.ProjectName, agentSettings.EnvironmentId, agentSettings.EnvironmentVMResourceId);
}
Trace.Info("Environment virtual machine resource with id: '{0}' has been successfully deleted.", agentSettings.EnvironmentVMResourceId);
Trace.Info($"Environment virtual machine resource with id: '{agentSettings.EnvironmentVMResourceId}' has been successfully deleted.");
}

public override async Task<TaskAgent> GetAgentAsync(AgentSettings agentSettings)
{
ArgUtil.NotNull(agentSettings, nameof(agentSettings));
var vmResources = await GetEnvironmentVMsAsync(agentSettings);
Trace.Verbose("Returns {0} virtual machine resources", vmResources.Count);
Trace.Verbose($"Returns {vmResources.Count} virtual machine resources");
var machine = vmResources.FirstOrDefault();
if (machine != null)
{
Expand All @@ -553,9 +553,9 @@ public override async Task<TaskAgent> UpdateAgentAsync(AgentSettings agentSettin

vmResource.Agent = agent;
vmResource.Tags = tags;
Trace.Info("Replacing environment virtual machine resource with id: '{0}'", vmResource.Id);
Trace.Info($"Replacing environment virtual machine resource with id: '{vmResource.Id}'");
vmResource = await _environmentsServer.ReplaceEnvironmentVMAsync(new Guid(agentSettings.ProjectId), agentSettings.EnvironmentId, vmResource);
Trace.Info("environment virtual machine resource with id: '{0}' has been replaced successfully", vmResource.Id);
Trace.Info($"environment virtual machine resource with id: '{vmResource.Id}' has been replaced successfully");
var pool = await _environmentsServer.GetEnvironmentPoolAsync(new Guid(agentSettings.ProjectId), agentSettings.EnvironmentId);

agentSettings.AgentName = vmResource.Name;
Expand Down
16 changes: 8 additions & 8 deletions src/Agent.Listener/Configuration/CredentialProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private Uri GetTenantAuthorityUrl(IHostContext context, string serverUrl)
}
catch (SocketException e)
{
ExceptionsUtil.HandleSocketException(e, serverUrl, trace.Error);
ExceptionsUtil.HandleSocketException(e, serverUrl, (message) => trace.Error(message));
throw;
}

Expand Down Expand Up @@ -214,7 +214,7 @@ public override VssCredentials GetVssCredentials(IHostContext context)

ArgUtil.NotNullOrEmpty(token, nameof(token));

trace.Info("token retrieved: {0} chars", token.Length);
trace.Info($"token retrieved: {token.Length} chars");

// PAT uses a basic credential
VssBasicCredential basicCred = new VssBasicCredential("VstsAgent", token);
Expand Down Expand Up @@ -259,7 +259,7 @@ public override VssCredentials GetVssCredentials(IHostContext context)
ArgUtil.NotNullOrEmpty(token, nameof(token));
ArgUtil.NotNullOrEmpty(username, nameof(username));

trace.Info("token retrieved: {0} chars", token.Length);
trace.Info($"token retrieved: {token.Length} chars");

// ServiceIdentity uses a service identity credential
VssServiceIdentityToken identityToken = new VssServiceIdentityToken(token);
Expand Down Expand Up @@ -306,8 +306,8 @@ public override VssCredentials GetVssCredentials(IHostContext context)
ArgUtil.NotNull(username, nameof(username));
ArgUtil.NotNull(password, nameof(password));

trace.Info("username retrieved: {0} chars", username.Length);
trace.Info("password retrieved: {0} chars", password.Length);
trace.Info($"username retrieved: {username.Length} chars");
trace.Info($"password retrieved: {password.Length} chars");

VssBasicCredential loginCred = new VssBasicCredential(username, password);
VssCredentials creds = new VssCredentials(null, loginCred, CredentialPromptType.DoNotPrompt);
Expand Down Expand Up @@ -339,15 +339,15 @@ public override VssCredentials GetVssCredentials(IHostContext context)

CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.TenantId, out string tenantId);
ArgUtil.NotNullOrEmpty(tenantId, nameof(tenantId));
trace.Info("tenant id retrieved: {0} chars", tenantId.Length);
trace.Info($"tenant id retrieved: {tenantId.Length} chars");

CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.ClientId, out string clientId);
ArgUtil.NotNullOrEmpty(clientId, nameof(clientId));
trace.Info("client id retrieved: {0} chars", clientId.Length);
trace.Info($"client id retrieved: {clientId.Length} chars");

CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.ClientSecret, out string clientSecret);
ArgUtil.NotNullOrEmpty(clientSecret, nameof(clientSecret));
trace.Info("client secret retrieved: {0} chars", clientSecret.Length);
trace.Info($"client secret retrieved: {clientSecret.Length} chars");

var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

Expand Down
Loading