Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there are nice way of logging function names when inside a lambda?

Tags:

c++

c++11

Our logging framework, like most logging frameworks, uses the __FUNCTION__ preprocessor macro to insert the current function into log files so that our logging looks like:

L4  T11332 609661594 [PreProcessorFunctions::RegenerateLinkIDs] [ENTER]
L4  T11332 609661594 [PreProcessorFunctions::RegenerateLinkIDs] [EXIT]
L4  T11332 609661594 [ConfigMerger::ValidateConfigObject] [ENTER]
L3  T11332 609661594 [ConfigMerger::ValidateConfigObject] Configuration Exists: 1

As we've started to use C++11 more, I've noticed that labmdas produce accurate yet unhelpful __FUNCTION__ output:

L4  T9604 609661594 [`anonymous-namespace'::<lambda1>::operator ()] Writing EMX config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\EMXConfiguration.xml
L4  T11332 609661594 [`anonymous-namespace'::<lambda3>::operator ()] Writing Auditing config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\Auditing.xml
L4  T11960 609661594 [`anonymous-namespace'::<lambda2>::operator ()] Writing UEM config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\Configuration.xml

As you can see, all class scope has been lost and all we now know is that this logging statement came from an anonymous lambda. Does anyone have a good strategy for logging out the enclosing function? This would appear to be the most useful thing to log...

like image 584
Benj Avatar asked Oct 04 '12 13:10

Benj


People also ask

What is __ Pretty_function __?

The identifier __PRETTY_FUNCTION__ holds the name of the function pretty printed in a language specific fashion. These names are always the same in a C function, but in a C++ function they may be different. For example, this program: extern "C" { extern int printf (char *, ...

How do you name a Lambda function?

The closest you can get to renaming the lambda function is using an alias, which is a way to name a specific version of a lambda. The actual name of the function though, is set once you create it. If you want to rename it, just create a new function and copy the exact same code into it.

How do you log inside a Lambda function?

Using the CloudWatch console You can use the Amazon CloudWatch console to view logs for all Lambda function invocations. Open the Log groups page on the CloudWatch console. Choose the log group for your function (/aws/lambda/ your-function-name ). Choose a log stream.


1 Answers

I think the only workaround would be to expand __FUNCTION__ (or __func__ in C++11) in the enclosing function and capture that inside the lambda.

void f(){
  auto& _func_ = __func__;
  [&]{ std::cout << _func_; };
}

I would tag this as a "quality of implementation" issue, though. GCC, for example, provides the __PRETTY_FUNCTION__ macro that expands much better for lambdas (and in general):

#include <iostream>

struct X{
  void f(){
    []{ std::cout << __PRETTY_FUNCTION__ << "\n"; }();
  }
};

int main(){
  X().f();
}

Output: X::f()::<lambda()>

Live example.

like image 110
Xeo Avatar answered Oct 11 '22 12:10

Xeo