diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 8181c0f02..906e2d706 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -403,6 +403,25 @@ trace_mem_per_thread_free(void)
 	rte_spinlock_unlock(&trace->lock);
 }
 
+void
+__rte_trace_emit_ctf_field(size_t sz, const char *in, const char *datatype)
+{
+	char *field = RTE_PER_LCORE(ctf_field);
+	int count = RTE_PER_LCORE(ctf_count);
+	int rc;
+
+	RTE_PER_LCORE(trace_point_sz) += sz;
+	rc = snprintf(RTE_PTR_ADD(field, count),
+		      RTE_MAX(0, TRACE_CTF_FIELD_SIZE - 1 - count),
+		      "%s %s;", datatype, in);
+	if (rc <= 0) {
+		RTE_PER_LCORE(trace_point_sz) = 0;
+		trace_crit("CTF field is too long");
+		return;
+	}
+	RTE_PER_LCORE(ctf_count) += rc;
+}
+
 int
 __rte_trace_point_register(rte_trace_t *handle, const char *name,
 			   void (*register_fn)(void))
diff --git a/lib/librte_eal/include/rte_trace.h b/lib/librte_eal/include/rte_trace.h
index cd9bf937f..b327ef44a 100644
--- a/lib/librte_eal/include/rte_trace.h
+++ b/lib/librte_eal/include/rte_trace.h
@@ -361,6 +361,8 @@ _tp _args \
 
 /** @internal Macro to define maximum emit length of string datatype. */
 #define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
+/** @internal Macro to define event header size. */
+#define __RTE_TRACE_EVENT_HEADER_SZ sizeof(uint64_t)
 
 /**
  * @internal
@@ -391,6 +393,24 @@ __rte_experimental
 int __rte_trace_point_register(rte_trace_t *trace, const char *name,
 			       void (*register_fn)(void));
 
+/**
+ * @internal
+ *
+ * Helper function to emit ctf field.
+ *
+ * @param sz
+ *   The tracepoint size.
+ * @param field
+ *   The name of the trace event.
+ * @param type
+ *   The datatype of the trace event as string.
+ * @return
+ *   - 0: Success.
+ *   - <0: Failure.
+ */
+__rte_experimental
+void __rte_trace_emit_ctf_field(size_t sz, const char *field, const char *type);
+
 #ifdef RTE_TRACE_POINT_REGISTER_SELECT
 #include <rte_trace_register.h>
 #else
diff --git a/lib/librte_eal/include/rte_trace_register.h b/lib/librte_eal/include/rte_trace_register.h
index b36c00827..6c55a4a9a 100644
--- a/lib/librte_eal/include/rte_trace_register.h
+++ b/lib/librte_eal/include/rte_trace_register.h
@@ -17,4 +17,36 @@ RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
 	__rte_trace_point_register(&__##trace, RTE_STR(name),\
 				   (void (*)(void)) trace)
 
+#define __rte_trace_emit_header_generic(t)\
+	RTE_PER_LCORE(trace_point_sz) = __RTE_TRACE_EVENT_HEADER_SZ
+
+#define __rte_trace_emit_header_fp(t) __rte_trace_emit_header_generic(t)
+
+#define __rte_trace_emit_datatype(in, type)\
+do {\
+	RTE_BUILD_BUG_ON(sizeof(type) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(type), RTE_STR(in), RTE_STR(type));\
+} while (0)
+
+#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in, uint64_t)
+#define rte_trace_ctf_i64(in) __rte_trace_emit_datatype(in, int64_t)
+#define rte_trace_ctf_u32(in) __rte_trace_emit_datatype(in, uint32_t)
+#define rte_trace_ctf_i32(in) __rte_trace_emit_datatype(in, int32_t)
+#define rte_trace_ctf_u16(in) __rte_trace_emit_datatype(in, uint16_t)
+#define rte_trace_ctf_i16(in) __rte_trace_emit_datatype(in, int16_t)
+#define rte_trace_ctf_u8(in) __rte_trace_emit_datatype(in, uint8_t)
+#define rte_trace_ctf_i8(in) __rte_trace_emit_datatype(in, int8_t)
+#define rte_trace_ctf_int(in) __rte_trace_emit_datatype(in, int32_t)
+#define rte_trace_ctf_long(in) __rte_trace_emit_datatype(in, long)
+#define rte_trace_ctf_float(in) __rte_trace_emit_datatype(in, float)
+#define rte_trace_ctf_double(in) __rte_trace_emit_datatype(in, double)
+#define rte_trace_ctf_ptr(in) __rte_trace_emit_datatype(in, uintptr_t)
+
+#define rte_trace_ctf_string(in)\
+do {\
+	RTE_SET_USED(in);\
+	__rte_trace_emit_ctf_field(__RTE_TRACE_EMIT_STRING_LEN_MAX,\
+				   RTE_STR(in)"[32]", "string_bounded_t");\
+} while (0)
+
 #endif /* _RTE_TRACE_REGISTER_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 1d478449b..155dd4e25 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -340,7 +340,9 @@ EXPERIMENTAL {
 	rte_log_can_log;
 	rte_thread_getname;
 	__rte_trace_mem_per_thread_alloc;
+	__rte_trace_emit_ctf_field;
 	__rte_trace_point_register;
+	per_lcore_trace_point_sz;
 	per_lcore_trace_mem;
 	rte_trace_global_is_enabled;
 	rte_trace_global_is_disabled;
