// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
#include "kudu/server/tcmalloc_metrics.h"

#include <cstddef>
#include <cstdint>
#include <functional>
#include <ostream>

#include <glog/logging.h>
#ifdef TCMALLOC_ENABLED
#include <gperftools/malloc_extension.h>
#endif

#include "kudu/util/metrics.h"

#ifndef TCMALLOC_ENABLED
#define TCM_ASAN_MSG " (Disabled - no tcmalloc in this build)"
#else
#define TCM_ASAN_MSG
#endif

// As of this writing, we expose all of the un-deprecated tcmalloc status metrics listed at:
// http://gperftools.googlecode.com/svn/trunk/doc/tcmalloc.html

METRIC_DEFINE_gauge_uint64(server, generic_current_allocated_bytes,
    "Heap Memory Usage", kudu::MetricUnit::kBytes,
    "Number of bytes used by the application. This will not typically match the memory "
    "use reported by the OS, because it does not include TCMalloc overhead or memory "
    "fragmentation." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

METRIC_DEFINE_gauge_uint64(server, generic_heap_size,
    "Reserved Heap Memory", kudu::MetricUnit::kBytes,
    "Bytes of system memory reserved by TCMalloc." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

METRIC_DEFINE_gauge_uint64(server, tcmalloc_pageheap_free_bytes,
    "Free Heap Memory", kudu::MetricUnit::kBytes,
    "Number of bytes in free, mapped pages in page heap. These bytes can be used to "
    "fulfill allocation requests. They always count towards virtual memory usage, and "
    "unless the underlying memory is swapped out by the OS, they also count towards "
    "physical memory usage." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

METRIC_DEFINE_gauge_uint64(server, tcmalloc_pageheap_unmapped_bytes,
    "Unmapped Heap Memory", kudu::MetricUnit::kBytes,
    "Number of bytes in free, unmapped pages in page heap. These are bytes that have "
    "been released back to the OS, possibly by one of the MallocExtension \"Release\" "
    "calls. They can be used to fulfill allocation requests, but typically incur a page "
    "fault. They always count towards virtual memory usage, and depending on the OS, "
    "typically do not count towards physical memory usage." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

METRIC_DEFINE_gauge_uint64(server, tcmalloc_max_total_thread_cache_bytes,
    "Thread Cache Memory Limit", kudu::MetricUnit::kBytes,
    "A limit to how much memory TCMalloc dedicates for small objects. Higher numbers "
    "trade off more memory use for -- in some situations -- improved efficiency." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

METRIC_DEFINE_gauge_uint64(server, tcmalloc_current_total_thread_cache_bytes,
    "Thread Cache Memory Usage", kudu::MetricUnit::kBytes,
    "A measure of some of the memory TCMalloc is using (for small objects)." TCM_ASAN_MSG,
    kudu::MetricLevel::kInfo);

#undef TCM_ASAN_MSG

namespace kudu {
namespace tcmalloc {

static uint64_t GetTCMallocPropValue(const char* prop) {
  size_t value = 0;
#ifdef TCMALLOC_ENABLED
  if (!MallocExtension::instance()->GetNumericProperty(prop, &value)) {
    LOG(DFATAL) << "Failed to get value of numeric tcmalloc property: " << prop;
  }
#endif
  return value;
}

void RegisterMetrics(const scoped_refptr<MetricEntity>& entity) {
  entity->NeverRetire(
      METRIC_generic_current_allocated_bytes.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("generic.current_allocated_bytes");
          }));
  entity->NeverRetire(
      METRIC_generic_heap_size.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("generic.heap_size");
          }));
  entity->NeverRetire(
      METRIC_tcmalloc_pageheap_free_bytes.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("tcmalloc.pageheap_free_bytes");
          }));
  entity->NeverRetire(
      METRIC_tcmalloc_pageheap_unmapped_bytes.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("tcmalloc.pageheap_unmapped_bytes");
          }));
  entity->NeverRetire(
      METRIC_tcmalloc_max_total_thread_cache_bytes.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("tcmalloc.max_total_thread_cache_bytes");
          }));
  entity->NeverRetire(
      METRIC_tcmalloc_current_total_thread_cache_bytes.InstantiateFunctionGauge(
          entity, []() {
            return GetTCMallocPropValue("tcmalloc.current_total_thread_cache_bytes");
          }));
}

} // namespace tcmalloc
} // namespace kudu
