Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
b71bd81c
Commit
b71bd81c
authored
Nov 03, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add customization point for injecting tracing data
parent
b05a4b7b
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
415 additions
and
16 deletions
+415
-16
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+2
-0
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+7
-0
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+5
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+4
-1
libcaf_core/caf/mailbox_element.hpp
libcaf_core/caf/mailbox_element.hpp
+25
-14
libcaf_core/caf/sec.hpp
libcaf_core/caf/sec.hpp
+2
-0
libcaf_core/caf/tracing_data.hpp
libcaf_core/caf/tracing_data.hpp
+48
-0
libcaf_core/caf/tracing_data_factory.hpp
libcaf_core/caf/tracing_data_factory.hpp
+37
-0
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+2
-1
libcaf_core/src/tracing_data.cpp
libcaf_core/src/tracing_data.cpp
+65
-0
libcaf_core/src/tracing_data_factory.cpp
libcaf_core/src/tracing_data_factory.cpp
+27
-0
libcaf_core/test/tracing_data.cpp
libcaf_core/test/tracing_data.cpp
+191
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
b71bd81c
...
...
@@ -149,6 +149,8 @@ set(LIBCAF_CORE_SRCS
src/term.cpp
src/thread_hook.cpp
src/timestamp.cpp
src/tracing_data.cpp
src/tracing_data_factory.cpp
src/type_erased_tuple.cpp
src/type_erased_value.cpp
src/uniform_type_info_map.cpp
...
...
libcaf_core/caf/actor_system.hpp
View file @
b71bd81c
...
...
@@ -588,6 +588,10 @@ public:
profiler_
->
before_sending_scheduled
(
self
,
timeout
,
element
);
}
tracing_data_factory
*
tracing_context
()
const
noexcept
{
return
tracing_context_
;
}
/// @endcond
private:
...
...
@@ -673,6 +677,9 @@ private:
/// Stores custom, system-wide key-value pairs.
runtime_settings_map
settings_
;
/// Stores the system-wide factory for deserializing tracing data.
tracing_data_factory
*
tracing_context_
;
};
}
// namespace caf
libcaf_core/caf/actor_system_config.hpp
View file @
b71bd81c
...
...
@@ -306,6 +306,11 @@ public:
/// @note Has no effect unless building CAF with CAF_ENABLE_ACTOR_PROFILER.
actor_profiler
*
profiler
=
nullptr
;
/// Enables CAF to deserialize application-specific tracing information.
/// @experimental
/// @note Has no effect unless building CAF with CAF_ENABLE_ACTOR_PROFILER.
tracing_data_factory
*
tracing_context
=
nullptr
;
// -- run-time type information ----------------------------------------------
portable_name_map
type_names_by_rtti
;
...
...
libcaf_core/caf/fwd.hpp
View file @
b71bd81c
...
...
@@ -135,6 +135,8 @@ class scoped_actor;
class
serializer
;
class
stream_manager
;
class
string_view
;
class
tracing_data
;
class
tracing_data_factory
;
class
type_erased_tuple
;
class
type_erased_value
;
class
uniform_type_info_map
;
...
...
@@ -301,7 +303,8 @@ using stream_manager_ptr = intrusive_ptr<stream_manager>;
// -- unique pointer aliases ---------------------------------------------------
using
type_erased_value_ptr
=
std
::
unique_ptr
<
type_erased_value
>
;
using
mailbox_element_ptr
=
std
::
unique_ptr
<
mailbox_element
,
detail
::
disposer
>
;
using
tracing_data_ptr
=
std
::
unique_ptr
<
tracing_data
>
;
using
type_erased_value_ptr
=
std
::
unique_ptr
<
type_erased_value
>
;
}
// namespace caf
libcaf_core/caf/mailbox_element.hpp
View file @
b71bd81c
...
...
@@ -19,25 +19,25 @@
#pragma once
#include <cstddef>
#include <memory>
#include "caf/actor_control_block.hpp"
#include "caf/config.hpp"
#include "caf/detail/disposer.hpp"
#include "caf/detail/tuple_vals.hpp"
#include "caf/detail/type_erased_tuple_view.hpp"
#include "caf/extend.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "caf/make_message.hpp"
#include "caf/memory_managed.hpp"
#include "caf/message.hpp"
#include "caf/message_id.hpp"
#include "caf/ref_counted.hpp"
#include "caf/make_message.hpp"
#include "caf/message_view.hpp"
#include "caf/memory_managed.hpp"
#include "caf/type_erased_tuple.hpp"
#include "caf/actor_control_block.hpp"
#include "caf/intrusive/singly_linked.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/
detail/disposer
.hpp"
#include "caf/
detail/tuple_vals
.hpp"
#include "caf/
detail/type_erased_tuple_view
.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/
ref_counted
.hpp"
#include "caf/
tracing_data
.hpp"
#include "caf/
type_erased_tuple
.hpp"
namespace
caf
{
...
...
@@ -57,6 +57,13 @@ public:
/// if this is empty then the original sender receives the response.
forwarding_stack
stages
;
#ifdef CAF_ENABLE_ACTOR_PROFILER
/// Optional tracing information. This field is unused by default, but an
/// @ref actor_profiler can make use of it to inject application-specific
/// instrumentation.
tracing_data_ptr
tracing_id
;
#endif // CAF_ENABLE_ACTOR_PROFILER
mailbox_element
();
mailbox_element
(
strong_actor_ptr
&&
x
,
message_id
y
,
...
...
@@ -101,7 +108,11 @@ struct mailbox_category_corrector<upstream_msg> {
template
<
class
Inspector
>
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
mailbox_element
&
x
)
{
return
f
(
meta
::
type_name
(
"mailbox_element"
),
x
.
sender
,
x
.
mid
,
meta
::
omittable_if_empty
(),
x
.
stages
,
x
.
content
());
meta
::
omittable_if_empty
(),
x
.
stages
,
#ifdef CAF_ENABLE_ACTOR_PROFILER
x
.
tracing_id
,
#endif // CAF_ENABLE_ACTOR_PROFILER
x
.
content
());
}
/// Encapsulates arbitrary data in a message element.
...
...
libcaf_core/caf/sec.hpp
View file @
b71bd81c
...
...
@@ -126,6 +126,8 @@ enum class sec : uint8_t {
unavailable_or_would_block
,
/// Resolving a path on a remote node failed.
remote_lookup_failed
,
/// Serialization failed because actor_system::tracing_context is null.
no_tracing_context
,
};
/// @relates sec
...
...
libcaf_core/caf/tracing_data.hpp
0 → 100644
View file @
b71bd81c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <memory>
#include "caf/fwd.hpp"
namespace
caf
{
/// Marker interface for application-specific tracing data. This interface
/// enables users to inject application-specific instrumentation into CAF's
/// messaging layer. CAF provides no default implementation for this
/// customization point.
class
tracing_data
{
public:
virtual
~
tracing_data
();
/// Writes the content of this object to `sink`.
virtual
error
serialize
(
serializer
&
sink
)
const
=
0
;
};
/// @relates tracing_data
using
tracing_data_ptr
=
std
::
unique_ptr
<
tracing_data
>
;
/// @relates tracing_data
error
inspect
(
serializer
&
sink
,
const
tracing_data_ptr
&
x
);
/// @relates tracing_data
error
inspect
(
deserializer
&
source
,
tracing_data_ptr
&
x
);
}
// namespace caf
libcaf_core/caf/tracing_data_factory.hpp
0 → 100644
View file @
b71bd81c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include "caf/fwd.hpp"
namespace
caf
{
/// Creates instances of @ref tracing_data.
class
tracing_data_factory
{
public:
virtual
~
tracing_data_factory
();
/// Deserializes tracing data from `source` and either overrides the content
/// of `dst` or allocates a new object if `dst` is null.
/// @returns the result of `source`.
virtual
error
deserialize
(
deserializer
&
source
,
std
::
unique_ptr
<
tracing_data
>&
dst
)
const
=
0
;
};
}
// namespace caf
libcaf_core/src/actor_system.cpp
View file @
b71bd81c
...
...
@@ -226,7 +226,8 @@ actor_system::actor_system(actor_system_config& cfg)
await_actors_before_shutdown_
(
true
),
detached_
(
0
),
cfg_
(
cfg
),
logger_dtor_done_
(
false
)
{
logger_dtor_done_
(
false
),
tracing_context_
(
cfg
.
tracing_context
)
{
CAF_SET_LOGGER_SYS
(
this
);
for
(
auto
&
hook
:
cfg
.
thread_hooks_
)
hook
->
init
(
*
this
);
...
...
libcaf_core/src/tracing_data.cpp
0 → 100644
View file @
b71bd81c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/tracing_data.hpp"
#include <cstdint>
#include "caf/actor_system.hpp"
#include "caf/deserializer.hpp"
#include "caf/error.hpp"
#include "caf/logger.hpp"
#include "caf/sec.hpp"
#include "caf/serializer.hpp"
#include "caf/tracing_data_factory.hpp"
namespace
caf
{
tracing_data
::~
tracing_data
()
{
// nop
}
error
inspect
(
serializer
&
sink
,
const
tracing_data_ptr
&
x
)
{
if
(
x
==
nullptr
)
{
uint8_t
dummy
=
0
;
return
sink
(
dummy
);
}
uint8_t
dummy
=
1
;
if
(
auto
err
=
sink
(
dummy
))
return
err
;
return
x
->
serialize
(
sink
);
}
error
inspect
(
deserializer
&
source
,
tracing_data_ptr
&
x
)
{
uint8_t
dummy
=
0
;
if
(
auto
err
=
source
(
dummy
))
return
err
;
if
(
dummy
==
0
)
{
x
.
reset
();
return
none
;
}
auto
ctx
=
source
.
context
();
if
(
ctx
==
nullptr
)
return
sec
::
no_context
;
auto
tc
=
ctx
->
system
().
tracing_context
();
if
(
tc
==
nullptr
)
return
sec
::
no_tracing_context
;
return
tc
->
deserialize
(
source
,
x
);
}
}
// namespace caf
libcaf_core/src/tracing_data_factory.cpp
0 → 100644
View file @
b71bd81c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/tracing_data_factory.hpp"
namespace
caf
{
tracing_data_factory
::~
tracing_data_factory
()
{
// nop
}
}
// namespace caf
libcaf_core/test/tracing_data.cpp
0 → 100644
View file @
b71bd81c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE tracing_data
#include "caf/tracing_data.hpp"
#include "caf/test/dsl.hpp"
#include <vector>
#include "caf/actor_profiler.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/config.hpp"
#include "caf/serializer_impl.hpp"
#include "caf/tracing_data_factory.hpp"
#ifdef CAF_ENABLE_ACTOR_PROFILER
using
std
::
string
;
using
namespace
caf
;
namespace
{
class
dummy_tracing_data
:
public
tracing_data
{
public:
string
value
;
dummy_tracing_data
(
string
value
)
:
value
(
std
::
move
(
value
))
{
// nop
}
error
serialize
(
serializer
&
sink
)
const
override
{
return
sink
(
value
);
}
};
class
dummy_tracing_data_factory
:
public
tracing_data_factory
{
public:
error
deserialize
(
deserializer
&
source
,
std
::
unique_ptr
<
tracing_data
>&
dst
)
const
override
{
string
value
;
if
(
auto
err
=
source
(
value
))
return
err
;
dst
.
reset
(
new
dummy_tracing_data
(
std
::
move
(
value
)));
return
none
;
}
};
class
dummy_profiler
:
public
actor_profiler
{
public:
void
add_actor
(
const
local_actor
&
,
const
local_actor
*
)
override
{
// nop
}
void
remove_actor
(
const
local_actor
&
)
override
{
// nop
}
void
before_processing
(
const
local_actor
&
,
const
mailbox_element
&
)
override
{
// nop
}
void
after_processing
(
const
local_actor
&
,
invoke_message_result
)
override
{
// nop
}
void
before_sending
(
const
local_actor
&
self
,
mailbox_element
&
element
)
override
{
element
.
tracing_id
.
reset
(
new
dummy_tracing_data
(
self
.
name
()));
}
void
before_sending_scheduled
(
const
local_actor
&
self
,
actor_clock
::
time_point
,
mailbox_element
&
element
)
override
{
element
.
tracing_id
.
reset
(
new
dummy_tracing_data
(
self
.
name
()));
}
};
actor_system_config
&
init
(
actor_system_config
&
cfg
,
actor_profiler
&
profiler
,
tracing_data_factory
&
factory
)
{
test_coordinator_fixture
<>::
init_config
(
cfg
);
cfg
.
profiler
=
&
profiler
;
cfg
.
tracing_context
=
&
factory
;
return
cfg
;
}
struct
fixture
{
using
scheduler_type
=
caf
::
scheduler
::
test_coordinator
;
fixture
()
:
sys
(
init
(
cfg
,
profiler
,
factory
)),
sched
(
dynamic_cast
<
scheduler_type
&>
(
sys
.
scheduler
()))
{
run
();
}
void
run
()
{
sched
.
run
();
}
dummy_profiler
profiler
;
dummy_tracing_data_factory
factory
;
actor_system_config
cfg
;
actor_system
sys
;
scheduler_type
&
sched
;
};
const
std
::
string
&
tracing_id
(
local_actor
*
self
)
{
auto
element
=
self
->
current_mailbox_element
();
if
(
element
==
nullptr
)
CAF_FAIL
(
"current_mailbox_element == null"
);
auto
tid
=
element
->
tracing_id
.
get
();
if
(
tid
==
nullptr
)
CAF_FAIL
(
"tracing_id == null"
);
auto
dummy_tid
=
dynamic_cast
<
dummy_tracing_data
*>
(
tid
);
if
(
dummy_tid
==
nullptr
)
CAF_FAIL
(
"dummy_tracing_id == null"
);
return
dummy_tid
->
value
;
}
# define NAMED_ACTOR_STATE(type) \
struct type##_state { \
const char* name = #type; \
}
NAMED_ACTOR_STATE
(
alice
);
NAMED_ACTOR_STATE
(
bob
);
NAMED_ACTOR_STATE
(
carl
);
}
// namespace
CAF_TEST_FIXTURE_SCOPE
(
actor_profiler_tests
,
fixture
)
CAF_TEST
(
profilers
inject
tracing
data
into
asynchronous
messages
)
{
CAF_MESSAGE
(
"spawn a foo and a bar"
);
auto
carl_fun
=
[](
stateful_actor
<
carl_state
>*
self
)
->
behavior
{
return
{
[
=
](
const
string
&
str
)
{
CAF_CHECK_EQUAL
(
str
,
"hello carl"
);
CAF_CHECK_EQUAL
(
tracing_id
(
self
),
"bob"
);
},
};
};
auto
bob_fun
=
[](
stateful_actor
<
bob_state
>*
self
,
actor
carl
)
->
behavior
{
return
{
[
=
](
const
string
&
str
)
{
CAF_CHECK_EQUAL
(
str
,
"hello bob"
);
CAF_CHECK_EQUAL
(
tracing_id
(
self
),
"alice"
);
self
->
send
(
carl
,
"hello carl"
);
},
};
};
auto
alice_fun
=
[](
stateful_actor
<
alice_state
>*
self
,
actor
bob
)
{
self
->
send
(
bob
,
"hello bob"
);
};
sys
.
spawn
(
alice_fun
,
sys
.
spawn
(
bob_fun
,
sys
.
spawn
(
carl_fun
)));
run
();
}
CAF_TEST
(
tracing
data
is
serializable
)
{
std
::
vector
<
byte
>
buf
;
serializer_impl
<
std
::
vector
<
byte
>>
sink
{
sys
,
buf
};
tracing_data_ptr
data
;
tracing_data_ptr
copy
;
data
.
reset
(
new
dummy_tracing_data
(
"iTrace"
));
CAF_CHECK_EQUAL
(
inspect
(
sink
,
data
),
none
);
binary_deserializer
source
{
sys
,
buf
};
CAF_CHECK_EQUAL
(
inspect
(
source
,
copy
),
none
);
CAF_REQUIRE_NOT_EQUAL
(
copy
.
get
(),
nullptr
);
CAF_CHECK_EQUAL
(
dynamic_cast
<
dummy_tracing_data
&>
(
*
copy
).
value
,
"iTrace"
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
#endif // CAF_ENABLE_ACTOR_PROFILER
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment