Skip to content

Commit

Permalink
feat: Parse Azure Function HttpTrigger parameters (#2776)
Browse files Browse the repository at this point in the history
  • Loading branch information
tippmar-nr authored Sep 23, 2024
1 parent e545c43 commit 7e8c28b
Show file tree
Hide file tree
Showing 16 changed files with 747 additions and 415 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class NoOpTransaction : ITransaction, ITransactionExperimental
public bool IsValid => false;
public bool IsFinished => false;
public ISegment CurrentSegment => Segment.NoOpSegment;
public bool HasHttpResponseStatusCode => false;

public DateTime StartTime => DateTime.UtcNow;

Expand Down
2 changes: 2 additions & 0 deletions src/Agent/NewRelic/Agent/Core/Transactions/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public ISegment CurrentSegment
}
}

public bool HasHttpResponseStatusCode => TransactionMetadata.HttpResponseStatusCode.HasValue;

public ITracingState TracingState { get; private set; }

public string TraceId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public interface ITransaction
/// </summary>
ISegment CurrentSegment { get; }

bool HasHttpResponseStatusCode { get; }

/// <summary>
/// End this transaction.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using NewRelic.Agent.Api;
using NewRelic.Agent.Extensions.Providers.Wrapper;

namespace NewRelic.Providers.Wrapper.AzureFunction;

public class FunctionsHttpProxyingMiddlewareWrapper : IWrapper
{
private const string WrapperName = "FunctionsHttpProxyingMiddlewareWrapper";

public bool IsTransactionRequired => false;

public CanWrapResponse CanWrap(InstrumentedMethodInfo methodInfo)
{
return new CanWrapResponse(WrapperName.Equals(methodInfo.RequestedWrapperName));
}

/// <summary>
/// Gets request method / path for Azure function HttpTrigger invocations
/// in apps that use the Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore package
/// </summary>
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction)
{
if (agent.Configuration.AzureFunctionModeEnabled)
{
dynamic httpContext;
switch (instrumentedMethodCall.MethodCall.Method.MethodName)
{
case "AddHttpContextToFunctionContext":
httpContext = instrumentedMethodCall.MethodCall.MethodArguments[1];

agent.CurrentTransaction.SetRequestMethod(httpContext.Request.Method);
agent.CurrentTransaction.SetUri(httpContext.Request.Path);
break;
case "TryHandleHttpResult":
if (!agent.CurrentTransaction.HasHttpResponseStatusCode) // these handlers seem to get called more than once; only set the status code one time
{
httpContext = instrumentedMethodCall.MethodCall.MethodArguments[2];
agent.CurrentTransaction.SetHttpResponseStatusCode(httpContext.Response.StatusCode);
}
break;
case "TryHandleOutputBindingsHttpResult":
if (!agent.CurrentTransaction.HasHttpResponseStatusCode) // these handlers seem to get called more than once; only set the status code one time
{
httpContext = instrumentedMethodCall.MethodCall.MethodArguments[1];
agent.CurrentTransaction.SetHttpResponseStatusCode(httpContext.Response.StatusCode);
}
break;
}
}

return Delegates.NoOp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,18 @@ SPDX-License-Identifier: Apache-2.0
<exactMethodMatcher methodName="Build" />
</match>
</tracerFactory>

<tracerFactory name="FunctionsHttpProxyingMiddlewareWrapper">
<match assemblyName="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" className="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware">
<exactMethodMatcher methodName="AddHttpContextToFunctionContext" />
</match>
<match assemblyName="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" className="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware">
<exactMethodMatcher methodName="TryHandleHttpResult" />
</match>
<match assemblyName="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" className="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware">
<exactMethodMatcher methodName="TryHandleOutputBindingsHttpResult" />
</match>

</tracerFactory>
</instrumentation>
</extension>
Loading

0 comments on commit 7e8c28b

Please sign in to comment.