All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.sinri.drydock.common.logging.adapter.AliyunSLSIssueAdapterImpl Maven / Gradle / Ivy

There is a newer version: 1.5.7
Show newest version
package io.github.sinri.drydock.common.logging.adapter;

import com.aliyun.openservices.aliyun.log.producer.LogProducer;
import com.aliyun.openservices.aliyun.log.producer.Producer;
import com.aliyun.openservices.aliyun.log.producer.ProducerConfig;
import com.aliyun.openservices.aliyun.log.producer.ProjectConfig;
import com.aliyun.openservices.log.common.LogItem;
import io.github.sinri.keel.facade.configuration.KeelConfigElement;
import io.github.sinri.keel.logger.issue.record.KeelIssueRecord;
import io.github.sinri.keel.logger.issue.recorder.adapter.AliyunSLSIssueAdapter;
import io.github.sinri.keel.logger.issue.recorder.adapter.SyncStdoutAdapter;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static io.github.sinri.keel.facade.KeelInstance.Keel;
import static io.github.sinri.keel.helper.KeelHelpersInterface.KeelHelpers;

/**
 * @since 1.3.4
 */
public class AliyunSLSIssueAdapterImpl extends AliyunSLSIssueAdapter {
    private final boolean disabled;
    private final String project;
    private final String logstore;
    private final String source;
    private final Producer producer;
    private final String endpoint;
    private volatile boolean stopped = false;
    private volatile boolean closed = true;

    /**
     * @return the configured switch to decide whether the Aliyun SLS should be disabled.
     * @since 1.4.9
     */
    public static boolean isDisabled() {
        String x = Keel.config("aliyun.sls.disabled");
        return "YES".equalsIgnoreCase(x);
    }

    public AliyunSLSIssueAdapterImpl() {
        KeelConfigElement aliyunSlsConfig = Keel.getConfiguration().extract("aliyun", "sls");
        if (aliyunSlsConfig == null) {
            disabled = true;
            this.project = null;
            this.logstore = null;
            this.endpoint = null;
            this.source = null;
        } else {
            String disabledString = aliyunSlsConfig.readString("disabled", null);
            // System.out.println("disabledString: "+disabledString);
            disabled = ("YES".equalsIgnoreCase(disabledString));

            this.project = aliyunSlsConfig.readString("project", null);
            this.logstore = aliyunSlsConfig.readString("logstore", null);
            this.endpoint = aliyunSlsConfig.readString("endpoint", null);
            this.source = buildSource(aliyunSlsConfig.readString("source", null));
        }
        if (!disabled) {
            String accessKeyId = aliyunSlsConfig.readString("accessKeyId", null);
            String accessKeySecret = aliyunSlsConfig.readString("accessKeySecret", null);

            producer = new LogProducer(new ProducerConfig());
            Objects.requireNonNull(project);
            Objects.requireNonNull(endpoint);
            Objects.requireNonNull(accessKeyId);
            Objects.requireNonNull(accessKeySecret);
            producer.putProjectConfig(new ProjectConfig(project, endpoint, accessKeyId, accessKeySecret));

            //KeelOutputEventLogCenter.getInstance().createLogger(getClass().getName()).info("Aliyun SLS Producer relied aliyunSlsConfig: " + aliyunSlsConfig.toJsonObject());
        } else {
            producer = null;
            // a bug in 1.4.2, to stdout not means closed.
        }
        closed = false;

        start();
    }

    /**
     * Build source from configuration.
     * Source Expression should be:
     * - EMPTY/BLANK STRING or NULL: use SLS default source generation;
     * - A TEMPLATED STRING
     * --- Rule 1: Replace [IP] to local address;
     */
    private static String buildSource(@Nullable String configuredSourceExpression) {
        if (configuredSourceExpression == null || configuredSourceExpression.isBlank()) {
            return "";
        }
        // Rule 1: Replace [IP] to local address
        String localHostAddress = KeelHelpers.netHelper().getLocalHostAddress();
        if (localHostAddress == null) {
            Keel.getLogger().warning("Could not get local host address for SLS source!");
            return "";
        }
        return configuredSourceExpression.replaceAll("\\[IP]", localHostAddress);
    }

    @Override
    protected Future handleIssueRecordsForTopic(@Nonnull final String topic, @Nonnull final List> buffer) {
        // Keel.getLogger().info("handleIssueRecordsForTopic["+topic+"] "+ buffer.size());
        if (buffer.isEmpty()) return Future.succeededFuture();

        if (disabled) {
            //Keel.getLogger().info("AliyunSLSIssueAdapterImpl handleIssueRecordsForTopic "+topic+" disabled");
            buffer.forEach(item -> {
                SyncStdoutAdapter.getInstance().record(topic, item);
            });
            return Future.succeededFuture();
        }

        Promise promise = Promise.promise();

        try {
            List logItems = new ArrayList<>();

            //Keel.getLogger().info("AliyunSLSIssueAdapterImpl handleIssueRecordsForTopic "+topic+" for each in buffer...");
            buffer.forEach(eventLog -> {
                LogItem logItem = new LogItem(Math.toIntExact(eventLog.timestamp() / 1000));
                logItem.PushBack(KeelIssueRecord.AttributeLevel, eventLog.level().name());
                List classification = eventLog.classification();
                if (!classification.isEmpty()) {
                    logItem.PushBack(KeelIssueRecord.AttributeClassification, String.valueOf(new JsonArray(classification)));
                }
                eventLog.attributes().forEach(entry -> {
                    if (entry.getValue() == null) {
                        logItem.PushBack(entry.getKey(), null);
                    } else {
                        logItem.PushBack(entry.getKey(), String.valueOf(entry.getValue()));
                    }
                });
                Throwable exception = eventLog.exception();
                if (exception != null) {
                    logItem.PushBack(KeelIssueRecord.AttributeException, String.valueOf(issueRecordRender().renderThrowable(exception)));
                }
                logItems.add(logItem);
            });
            //Keel.getLogger().info("AliyunSLSIssueAdapterImpl handleIssueRecordsForTopic "+topic+" buffer to send with producer");
            producer.send(project, logstore, topic, source, logItems, result -> {
                if (!result.isSuccessful()) {
                    Keel.getLogger().error(r -> r
                            .classification(getClass().getName())
                            .message("Producer Send Error: " + result)
                    );
                }

                //Keel.getLogger().info("AliyunSLSIssueAdapterImpl handleIssueRecordsForTopic "+topic+" promise to complete");
                promise.complete(null);
            });
        } catch (Throwable e) {
            Keel.getLogger().exception(e, r -> r
                    .classification(getClass().getName())
                    .message("Aliyun SLS Producer Exception")
            );
            promise.fail(e);
        }

        return promise.future();
    }

    @Override
    public boolean isStopped() {
        return stopped;
    }

    @Override
    public boolean isClosed() {
        return closed;
    }

    @Override
    public void close(@Nonnull Promise promise) {
        stopped = true;
        if (this.disabled || this.producer == null || closed) {
            closed = true;
            promise.complete();
        } else {
            try {
                this.producer.close();
                closed = true;
                promise.complete();
            } catch (Throwable e) {
                promise.fail(e);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy