func initialiseMetrics(log *logger.Logger) (map[string]*metricData, error) {
	metrics := make(map[string]*metricData)
	validMetrics := true
	metricNamesMap := generateMetricNamesMap()
	for _, metricClass := range mqmetric.Metrics.Classes {
		for _, metricType := range metricClass.Types {
			if !strings.Contains(metricType.ObjectTopic, "%s") {
				for _, metricElement := range metricType.Elements {
					key := makeKey(metricElement)
					if metricLookup, found := metricNamesMap[key]; found {
						if metricLookup.enabled {
							isDelta := false
							if metricElement.Datatype == ibmmq.MQIAMO_MONITOR_DELTA {
								isDelta = true
							}
							metric := metricData{
								name:        metricLookup.name,
								description: metricElement.Description,
								isDelta:     isDelta,
							}
							if _, exists := metrics[key]; !exists {
								metrics[key] = &metric
							} else {
								log.Errorf("Metrics Error: Found duplicate metric key [%s]", key)
								validMetrics = false
							}
						} else {
							log.Debugf("Metrics: Skipping metric, metric is not enabled for key [%s]", key)
						}
					} else {
						log.Errorf("Metrics Error: Skipping metric, unexpected key [%s]", key)
						validMetrics = false
					}
				}
			}
		}
	}
	if !validMetrics {
		return metrics, fmt.Errorf("Invalid metrics data")
	}
	return metrics, nil
}
initialiseMetrics sets initial details for all available metrics
package metrics
import (
	"fmt"
	"strings"
	"time"
	"github.com/ibm-messaging/mq-container/pkg/logger"
	"github.com/ibm-messaging/mq-golang/ibmmq"
	"github.com/ibm-messaging/mq-golang/mqmetric"
)
const (
	qmgrLabelValue = mqmetric.QMgrMapKey
	requestTimeout = 10
)
var (
	startChannel    = make(chan bool)
	stopChannel     = make(chan bool, 2)
	requestChannel  = make(chan bool)
	responseChannel = make(chan map[string]*metricData)
)
type metricData struct {
	name        string
	description string
	objectType  bool
	values      map[string]float64
	isDelta     bool
}
func processMetrics(log *logger.Logger, qmName string) {
	var err error
	var firstConnect = true
	var metrics map[string]*metricData
	for {
		err = doConnect(qmName)
		if err == nil {
			if firstConnect {
				firstConnect = false
				startChannel <- true
			}
			metrics, _ = initialiseMetrics(log)
		}
		for err == nil {
			err = mqmetric.ProcessPublications()
			if err == nil {
				select {
				case collect := <-requestChannel:
					if collect {
						updateMetrics(metrics)
					}
					responseChannel <- metrics
				case <-stopChannel:
					log.Println("Stopping metrics gathering")
					mqmetric.EndConnection()
					return
				case <-time.After(requestTimeout * time.Second):
					log.Debugf("Metrics: No requests received within timeout period (%d seconds)", requestTimeout)
				}
			}
		}
		log.Errorf("Metrics Error: %s", err.Error())
		mqmetric.EndConnection()
		select {
		case <-stopChannel:
			log.Println("Stopping metrics gathering")
			return
		case <-time.After(requestTimeout * time.Second):
			log.Println("Retrying metrics gathering")
		}
	}
}
func doConnect(qmName string) error {
	var connConfig mqmetric.ConnectionConfig
	connConfig.ClientMode = false
	connConfig.UserId = ""
	connConfig.Password = ""
	err := mqmetric.InitConnectionStats(qmName, "SYSTEM.DEFAULT.MODEL.QUEUE", "", &connConfig)
	if err != nil {
		return fmt.Errorf("Failed to connect to queue manager %s: %v", qmName, err)
	}
	err = mqmetric.DiscoverAndSubscribe("", true, "")
	if err != nil {
		return fmt.Errorf("Failed to discover and subscribe to metrics: %v", err)
	}
	return nil
}