Todos los productos
Search
Centro de documentos

Simple Log Service:Consumo de registros con un grupo de consumidores

Última actualización: Sep 22, 2026

Para consumir datos de Log Service en tiempo real mediante un SDK, es necesario gestionar detalles de implementación como el balanceo de carga y el failover entre consumidores. Un grupo de consumidores se encarga de estas complejidades por usted y permite consumir los datos casi en tiempo real, generalmente en cuestión de segundos.

Descripción general

Un logstore contiene varios shards. Un grupo de consumidores consume los datos al asignar estos shards a sus consumidores según las siguientes reglas:

  • Cada shard se asigna a un solo consumidor a la vez.

  • A un mismo consumidor se le pueden asignar varios shards.

Cuando un nuevo consumidor se une a un grupo de consumidores, este redistribuye los shards entre todos los consumidores para garantizar el balanceo de carga. Se aplican las mismas reglas.

image

Conceptos clave

Término

Descripción

consumer group

Un grupo de consumidores está formado por varios consumidores que consumen conjuntamente los datos de un mismo logstore sin duplicarlos.

Importante

Puede crear hasta 30 grupos de consumidores por cada logstore.

consumer

Es la unidad básica de un grupo de consumidores que ejecuta el consumo real de los datos.

Importante

Los consumidores de un mismo grupo deben tener nombres únicos.

Logstore

Unidad para recopilar, almacenar y consultar datos. Para obtener más información, consulte Logstore.

shard

Unidad que controla la capacidad de lectura y escritura de un logstore. Los datos siempre se almacenan en un shard. Para obtener más información, consulte shard.

checkpoint

La posición en un flujo de datos que marca el último dato procesado por un consumidor. Esto permite que el consumidor reanude el procesamiento desde ese punto después de reiniciarse.

Nota

Cuando consume datos mediante un grupo de consumidores, los checkpoints se guardan automáticamente si el programa falla. Una vez que el programa se recupera, puede continuar consumiendo los datos desde el último checkpoint. Esto evita el consumo duplicado.

Requisitos previos

Paso 1: Crear un grupo de consumidores

Nota

No es posible crear un grupo de consumidores directamente en la consola web de SLS. Solo puede crearlo mediante el SDK, la API o la CLI.

Puede crear un grupo de consumidores mediante el SDK, la API o la CLI.

SDK

El siguiente código crea un grupo de consumidores:

CreateConsumerGroup.java

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.common.ConsumerGroup;
import com.aliyun.openservices.log.exception.LogException;

public class CreateConsumerGroup {
    public static void main(String[] args) throws LogException {
         // This example obtains the AccessKey ID and AccessKey secret from environment variables.
        String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // Enter the project name.
        String projectName = "ali-test-project";
        // Enter the Logstore name.
        String logstoreName = "ali-test-logstore";
        // Set the endpoint for Simple Log Service. This example uses the endpoint of the China (Hangzhou) region. Replace it with the actual endpoint.
        String host = "https://cn-hangzhou.log.aliyuncs.com";

        // Create a Simple Log Service client.
        Client client = new Client(host, accessId, accessKey);

        try {
            // Set the consumer group name.
            String consumerGroupName = "ali-test-consumergroup2";
            System.out.println("ready to create consumergroup");

            ConsumerGroup consumerGroup = new ConsumerGroup(consumerGroupName, 300, true);

            client.CreateConsumerGroup(projectName, logstoreName, consumerGroup);

            System.out.println(String.format("create consumergroup %s success", consumerGroupName));

        } catch (LogException e) {
            System.out.println("LogException e :" + e.toString());
            System.out.println("error code :" + e.GetErrorCode());
            System.out.println("error message :" + e.GetErrorMessage());
            throw e;
        }
    }
}

Para ver ejemplos de código sobre cómo gestionar grupos de consumidores, consulte Use the Java SDK to manage consumer groups y Use Simple Log Service SDK for Python to manage consumer groups.

API

Para crear un grupo de consumidores mediante la API, consulte CreateConsumerGroup.

Para comprobar que el grupo de consumidores se creó correctamente, consulte ListConsumerGroup.

CLI

Para crear un grupo de consumidores mediante la CLI, consulte create_consumer_group.

Para comprobar que el grupo de consumidores se creó correctamente, consulte list_consumer_group.

Paso 2: Consumir datos de registro

Funcionamiento

Cuando un consumidor que utiliza el SDK del grupo de consumidores se inicia por primera vez, el SDK crea el grupo si aún no existe. El checkpoint inicial define la posición de partida del consumo y solo se usa cuando se crea el grupo por primera vez. En los reinicios posteriores, el consumidor continúa desde el último checkpoint que guardó el servidor. Por ejemplo:

  • LogHubConfig.ConsumePosition.BEGIN_CURSOR: el grupo de consumidores comienza a consumir desde el primer registro del logstore.

  • LogHubConfig.ConsumePosition.END_CURSOR: el grupo de consumidores comienza a consumir después del último registro del logstore.

Ejemplos

Puede consumir datos con un grupo de consumidores mediante los SDK de Java, C++, Python y Go. A continuación se muestran ejemplos con Java.

Ejemplo 1: consumo con SDK

  1. Agregue las dependencias de Maven.

    En su archivo pom.xml, agregue las siguientes dependencias:

    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>2.5.0</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun.openservices</groupId>
      <artifactId>loghub-client-lib</artifactId>
      <version>0.6.50</version>
    </dependency>
  2. Cree una clase para definir la lógica de procesamiento de sus registros.

    SampleLogHubProcessor.java

    import com.aliyun.openservices.log.common.FastLog;
    import com.aliyun.openservices.log.common.FastLogContent;
    import com.aliyun.openservices.log.common.FastLogGroup;
    import com.aliyun.openservices.log.common.FastLogTag;
    import com.aliyun.openservices.log.common.LogGroupData;
    import com.aliyun.openservices.loghub.client.ILogHubCheckPointTracker;
    import com.aliyun.openservices.loghub.client.exceptions.LogHubCheckPointException;
    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessor;
    import java.util.List;
    public class SampleLogHubProcessor implements ILogHubProcessor {
        private int shardId;
        // Tracks the last time a checkpoint was saved.
        private long mLastSaveTime = 0;
        // Called once upon processor initialization.
        public void initialize(int shardId) {
            this.shardId = shardId;
        }
        // The main logic for consuming data. All exceptions must be handled within this method. Do not throw exceptions directly.
        public String process(List<LogGroupData> logGroups, ILogHubCheckPointTracker checkPointTracker) {
            // Print the fetched data.
            for (LogGroupData logGroup : logGroups) {
                FastLogGroup fastLogGroup = logGroup.GetFastLogGroup();
                System.out.println("Tags");
                for (int i = 0; i < fastLogGroup.getLogTagsCount(); ++i) {
                    FastLogTag logTag = fastLogGroup.getLogTags(i);
                    System.out.printf("%s : %s\n", logTag.getKey(), logTag.getValue());
                }
                for (int i = 0; i < fastLogGroup.getLogsCount(); ++i) {
                    FastLog log = fastLogGroup.getLogs(i);
                    System.out.println("--------\nLog: " + i + ", time: " + log.getTime() + ", GetContentCount: " + log.getContentsCount());
                    for (int j = 0; j < log.getContentsCount(); ++j) {
                        FastLogContent content = log.getContents(j);
                        System.out.println(content.getKey() + "\t:\t" + content.getValue());
                    }
                }
            }
            long curTime = System.currentTimeMillis();
            // Save a checkpoint to the server every 30 seconds. If the worker terminates unexpectedly, the new worker resumes from the last checkpoint, potentially reprocessing a small amount of data.
            try {
                if (curTime - mLastSaveTime > 30 * 1000) {
                    // A 'true' parameter flushes the checkpoint to the server immediately. By default, the in-memory checkpoint is automatically flushed to the server every 60 seconds.
                    checkPointTracker.saveCheckPoint(true);
                    mLastSaveTime = curTime;
                } else {
                    // A 'false' parameter caches the checkpoint locally. It will be flushed to the server by the auto-update mechanism.
                    checkPointTracker.saveCheckPoint(false);
                }
            } catch (LogHubCheckPointException e) {
                e.printStackTrace();
            }
            return null;
        }
        // This method is called when the worker is shutting down. You can perform cleanup tasks here.
        public void shutdown(ILogHubCheckPointTracker checkPointTracker) {
            // Save the checkpoint to the server immediately.
            try {
                checkPointTracker.saveCheckPoint(true);
            } catch (LogHubCheckPointException e) {
                e.printStackTrace();
            }
        }
    }

    Para ver más ejemplos de código, consulte los repositorios aliyun-log-consumer-java y Aliyun LOG Go Consumer.

  3. Cree una fábrica para generar instancias de su procesador de registros.

    SampleLogHubProcessorFactory.java

    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessor;
    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessorFactory;
    class SampleLogHubProcessorFactory implements ILogHubProcessorFactory {
        public ILogHubProcessor generatorProcessor() {
            // Generate a consumer instance. Note: Each call to the generatorProcessor method should return a new SampleLogHubProcessor object.
            return new SampleLogHubProcessor();
        }
    }
  4. Cree una clase principal para configurar e iniciar el hilo de trabajo.

    Main.java

    import com.aliyun.openservices.loghub.client.ClientWorker;
    import com.aliyun.openservices.loghub.client.config.LogHubConfig;
    import com.aliyun.openservices.loghub.client.exceptions.LogHubClientWorkerException;
    public class Main {
        // The endpoint of Simple Log Service. Replace with your actual endpoint.
        private static String Endpoint = "cn-hangzhou.log.aliyuncs.com";
        // The project name. Replace with the name of an existing project.
        private static String Project = "ali-test-project";
        // The Logstore name. Replace with the name of an existing Logstore.
        private static String Logstore = "ali-test-logstore";
        // You do not need to create the consumer group beforehand; the program automatically creates it on the first run.
        private static String ConsumerGroup = "ali-test-consumergroup2";
        // This example retrieves the AccessKey ID and AccessKey Secret from environment variables.
        private static String AccessKeyId= System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        private static String AccessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        public static void main(String[] args) throws LogHubClientWorkerException, InterruptedException {
            // "consumer_1" is the consumer name, which must be unique within a consumer group. To balance consumption across multiple machines, you can use unique identifiers like the machine's IP address as the consumer name.
            // maxFetchLogGroupSize sets the maximum number of LogGroups to fetch per request. The default value is usually sufficient. You can adjust it by using config.setMaxFetchLogGroupSize(100). The valid range is (0, 1000].
            LogHubConfig config = new LogHubConfig(ConsumerGroup, "consumer_1", Endpoint, Project, Logstore, AccessKeyId, AccessKeySecret, LogHubConfig.ConsumePosition.BEGIN_CURSOR,1000);
            ClientWorker worker = new ClientWorker(new SampleLogHubProcessorFactory(), config);
            Thread thread = new Thread(worker);
            // After the thread starts, the ClientWorker runs automatically. ClientWorker implements the Runnable interface.
            thread.start();
            Thread.sleep(60 * 60 * 1000);
            // Call the worker's shutdown() method to stop the consumer instance and its associated thread.
            worker.shutdown();
            // The ClientWorker creates asynchronous tasks. After shutdown(), wait for these tasks to complete gracefully. A 30-second sleep is recommended.
            Thread.sleep(30 * 1000);
        }
    }
  5. Ejecute Main.java.

    A continuación se muestra un ejemplo de la salida al consumir registros de NGINX:

    :    GET
    request_uri    :    /request/path-3/file-7
    status    :    200
    body_bytes_sent    :    3820
    host    :    www.example.com
    request_time    :    43
    request_length    :    1987
    http_user_agent    :    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
    http_referer    :    www.example.com
    http_x_forwarded_for    :    192.168.10.196
    upstream_response_time    :    0.02
    --------
    Log: 158, time: 1635629778, GetContentCount: 14
    ......
        category    :    null
        source    :    127.0.0.1
        topic    :    nginx_access_log
        machineUUID    :    null
    Tags
        __receive_time__    :    1635629815
    --------
    Log: 0, time: 1635629788, GetContentCount: 14
    ......
        category    :    null
        source    :    127.0.0.1
        topic    :    nginx_access_log
        machineUUID    :    null
    Tags
        __receive_time__    :    1635629877
    --------
    ......

Ejemplo 2: consumo con SDK y SPL

  1. Agregue las dependencias de Maven.

    En su archivo pom.xml, agregue las siguientes dependencias:

    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>2.5.0</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun.openservices</groupId>
      <artifactId>loghub-client-lib</artifactId>
      <version>0.6.50</version>
    </dependency>
  2. Cree una clase para definir la lógica de procesamiento de sus registros.

    SPLLogHubProcessor.java

    import com.aliyun.openservices.log.common.FastLog;
    import com.aliyun.openservices.log.common.FastLogContent;
    import com.aliyun.openservices.log.common.FastLogGroup;
    import com.aliyun.openservices.log.common.FastLogTag;
    import com.aliyun.openservices.log.common.LogGroupData;
    import com.aliyun.openservices.loghub.client.ILogHubCheckPointTracker;
    import com.aliyun.openservices.loghub.client.exceptions.LogHubCheckPointException;
    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessor;
    import java.util.List;
    public class SPLLogHubProcessor implements ILogHubProcessor {
        private int shardId;
        // Tracks the last time a checkpoint was saved.
        private long mLastSaveTime = 0;
        // Called once upon processor initialization.
        public void initialize(int shardId) {
            this.shardId = shardId;
        }
        // The main logic for consuming data. All exceptions must be handled within this method. Do not throw exceptions directly.
        public String process(List<LogGroupData> logGroups, ILogHubCheckPointTracker checkPointTracker) {
            // Print the fetched data.
            for (LogGroupData logGroup : logGroups) {
                FastLogGroup fastLogGroup = logGroup.GetFastLogGroup();
                System.out.println("Tags");
                for (int i = 0; i < fastLogGroup.getLogTagsCount(); ++i) {
                    FastLogTag logTag = fastLogGroup.getLogTags(i);
                    System.out.printf("%s : %s\n", logTag.getKey(), logTag.getValue());
                }
                for (int i = 0; i < fastLogGroup.getLogsCount(); ++i) {
                    FastLog log = fastLogGroup.getLogs(i);
                    System.out.println("--------\nLog: " + i + ", time: " + log.getTime() + ", GetContentCount: " + log.getContentsCount());
                    for (int j = 0; j < log.getContentsCount(); ++j) {
                        FastLogContent content = log.getContents(j);
                        System.out.println(content.getKey() + "\t:\t" + content.getValue());
                    }
                }
            }
            long curTime = System.currentTimeMillis();
            // Save a checkpoint to the server every 30 seconds. If the worker terminates unexpectedly, the new worker resumes from the last checkpoint, potentially reprocessing a small amount of data.
            try {
                if (curTime - mLastSaveTime > 30 * 1000) {
                    // A 'true' parameter flushes the checkpoint to the server immediately. By default, the in-memory checkpoint is automatically flushed to the server every 60 seconds.
                    checkPointTracker.saveCheckPoint(true);
                    mLastSaveTime = curTime;
                } else {
                    // A 'false' parameter caches the checkpoint locally. It will be flushed to the server by the auto-update mechanism.
                    checkPointTracker.saveCheckPoint(false);
                }
            } catch (LogHubCheckPointException e) {
                e.printStackTrace();
            }
            return null;
        }
        // This method is called when the worker is shutting down. You can perform cleanup tasks here.
        public void shutdown(ILogHubCheckPointTracker checkPointTracker) {
            // Save the checkpoint to the server immediately.
            try {
                checkPointTracker.saveCheckPoint(true);
            } catch (LogHubCheckPointException e) {
                e.printStackTrace();
            }
        }
    }
  3. Cree una fábrica para generar instancias de su procesador de registros.

    SPLLogHubProcessorFactory.java

    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessor;
    import com.aliyun.openservices.loghub.client.interfaces.ILogHubProcessorFactory;
    class SPLLogHubProcessorFactory implements ILogHubProcessorFactory {
        public ILogHubProcessor generatorProcessor() {
            // Generate a consumer instance. Note: Each call to the generatorProcessor method should return a new SPLLogHubProcessor object.
            return new SPLLogHubProcessor();
        }
    }
  4. Cree una clase principal para configurar e iniciar el hilo de trabajo.

    Main.java

    import com.aliyun.openservices.loghub.client.ClientWorker;
    import com.aliyun.openservices.loghub.client.config.LogHubConfig;
    import com.aliyun.openservices.loghub.client.exceptions.LogHubClientWorkerException;
    public class Main {
        // The endpoint of Simple Log Service. Replace with your actual endpoint.
        private static String Endpoint = "cn-hangzhou.log.aliyuncs.com";
        // The project name. Replace with the name of an existing project.
        private static String Project = "ali-test-project";
        // The Logstore name. Replace with the name of an existing Logstore.
        private static String Logstore = "ali-test-logstore";
        // You do not need to create the consumer group beforehand; the program automatically creates it on the first run.
        private static String ConsumerGroup = "ali-test-consumergroup2";
        // This example retrieves the AccessKey ID and AccessKey Secret from environment variables.
        private static String AccessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        private static String AccessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        public static void main(String[] args) throws LogHubClientWorkerException, InterruptedException {
            // "consumer_1" is the consumer name, which must be unique within a consumer group. To balance consumption across multiple machines, you can use unique identifiers like the machine's IP address as the consumer name.
            // maxFetchLogGroupSize sets the maximum number of LogGroups to fetch per request. The default value is usually sufficient. You can adjust it by using config.setMaxFetchLogGroupSize(100). The valid range is (0, 1000].
            LogHubConfig config = new LogHubConfig(ConsumerGroup, "consumer_1", Endpoint, Project, Logstore, AccessKeyId, AccessKeySecret, LogHubConfig.ConsumePosition.BEGIN_CURSOR, 1000);
            // Use setQuery to specify an SPL statement to filter logs during consumption.
            config.setQuery("* | where cast(body_bytes_sent as bigint) > 14000");
            ClientWorker worker = new ClientWorker(new SPLLogHubProcessorFactory(), config);
            Thread thread = new Thread(worker);
            // After the thread starts, the ClientWorker runs automatically. ClientWorker implements the Runnable interface.
            thread.start();
            Thread.sleep(60 * 60 * 1000);
            // Call the worker's shutdown() method to stop the consumer instance and its associated thread.
            worker.shutdown();
            // The ClientWorker creates asynchronous tasks. After shutdown(), wait for these tasks to complete gracefully. A 30-second sleep is recommended.
            Thread.sleep(30 * 1000);
        }
    }
  5. Ejecute Main.java.

    A continuación se muestra un ejemplo de la salida al consumir registros de NGINX:

    :    GET
    request_uri    :    /request/path-3/file-7
    status    :    200
    body_bytes_sent    :    3820
    host    :    www.example.com
    request_time    :    43
    request_length    :    1987
    http_user_agent    :    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
    http_referer    :    www.example.com
    http_x_forwarded_for    :    192.168.10.196
    upstream_response_time    :    0.02
    --------
    Log: 158, time: 1635629778, GetContentCount: 14
    ......
        category    :    null
        source    :    127.0.0.1
        topic    :    nginx_access_log
        machineUUID    :    null
    Tags
        __receive_time__    :    1635629815
    --------
    Log: 0, time: 1635629788, GetContentCount: 14
    ......
        category    :    null
        source    :    127.0.0.1
        topic    :    nginx_access_log
        machineUUID    :    null
    Tags
        __receive_time__    :    1635629877
    --------
    ......

Paso 3: Consultar el estado del grupo de consumidores

Puede consultar el estado de un grupo de consumidores mediante uno de los siguientes métodos:

SDK de Java

  1. Consulte el checkpoint de consumo de cada shard. El siguiente código muestra un ejemplo:

    ConsumerGroupTest.java

    import java.util.List;
    import com.aliyun.openservices.log.Client;
    import com.aliyun.openservices.log.common.Consts.CursorMode;
    import com.aliyun.openservices.log.common.ConsumerGroup;
    import com.aliyun.openservices.log.common.ConsumerGroupShardCheckPoint;
    import com.aliyun.openservices.log.exception.LogException;
    public class ConsumerGroupTest {
        static String endpoint = "cn-hangzhou.log.aliyuncs.com";
        static String project = "ali-test-project";
        static String logstore = "ali-test-logstore";
        static String accesskeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        static String accesskey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        public static void main(String[] args) throws LogException {
            Client client = new Client(endpoint, accesskeyId, accesskey);
            // Get all consumer groups in the Logstore. The list is empty if no consumer groups exist.
            List<ConsumerGroup> consumerGroups = client.ListConsumerGroup(project, logstore).GetConsumerGroups();
            for(ConsumerGroup c: consumerGroups){
                // Print the consumer group properties: name, heartbeat timeout, and ordered consumption status.
                System.out.println("Name: " + c.getConsumerGroupName());
                System.out.println("heartbeat timeout: " + c.getTimeout());
                System.out.println("ordered consumption: " + c.isInOrder());
                for(ConsumerGroupShardCheckPoint cp: client.GetCheckPoint(project, logstore, c.getConsumerGroupName()).GetCheckPoints()){
                    System.out.println("shard: " + cp.getShard());
                    // The time is a long integer, accurate to the microsecond.
                    System.out.println("Last checkpoint update time: " + cp.getUpdateTime());
                    System.out.println("Consumer name: " + cp.getConsumer());
                    String consumerPrg = "";
                    if(cp.getCheckPoint().isEmpty())
                        consumerPrg = "Consumption has not started";
                    else{
                        // A UNIX timestamp in seconds. Format the output as needed.
                        try{
                            int prg = client.GetPrevCursorTime(project, logstore, cp.getShard(), cp.getCheckPoint()).GetCursorTime();
                            consumerPrg = "" + prg;
                        }
                        catch(LogException e){
                            if(e.GetErrorCode() == "InvalidCursor")
                                consumerPrg = "Invalid. The consumption checkpoint is older than the data retention period.";
                            else{
                                // internal server error
                                throw e;
                            }
                        }
                    }
                    System.out.println("consumption checkpoint: " + consumerPrg);
                    String endCursor = client.GetCursor(project, logstore, cp.getShard(), CursorMode.END).GetCursor();
                    int endPrg = 0;
                    try{
                        endPrg = client.GetPrevCursorTime(project, logstore, cp.getShard(), endCursor).GetCursorTime();
                    }
                    catch(LogException e){
                        // do nothing
                    }
                    // A UNIX timestamp in seconds. Format the output as needed.
                    System.out.println("Arrival time of the last record: " + endPrg);
                }
            }
        }
    }
  2. A continuación se muestra un ejemplo de la salida:

    Name: ali-test-consumergroup2
    heartbeat timeout: 60
    ordered consumption: false
    shard: 0
    Last checkpoint update time: 0
    Consumer name: consumer_1
    consumption checkpoint: Consumption has not started
    Arrival time of the last record: 1729583617
    shard: 1
    Last checkpoint update time: 0
    Consumer name: consumer_1
    consumption checkpoint: Consumption has not started
    Arrival time of the last record: 1729583738
    Process finished with exit code 0

Consola

  1. Inicie sesión en la consola de Simple Log Service.

  2. En la sección Projects, haga clic en el proyecto deseado.

    image

  3. En la pestaña Log Storage > Logstores, haga clic en el icono 展开节点 situado a la izquierda del logstore correspondiente y, a continuación, haga clic en el icono 展开节点 a la izquierda de Data Consumption.

  4. En la lista de grupos de consumidores, haga clic en el grupo deseado.

  5. En la página Consumer Group Status, consulte el checkpoint de consumo de cada shard. Esta página muestra los detalles de cada shard, incluidos su identificador (shard), la hora del último consumo (Last Consumed Time) y el Client que lo consume. También puede usar los botones Refresh y Reset Checkpoint.

Operaciones relacionadas

  • Autorización de usuarios de RAM

    Para gestionar grupos de consumidores con un usuario de RAM, otorgue los permisos necesarios a dicho usuario. Para obtener más información, consulte Create and authorize a RAM user.

    En la siguiente tabla se enumeran las acciones (Actions) obligatorias.

    Acción

    Descripción

    Recurso

    log:GetCursorOrData(GetCursor)

    Obtiene un cursor a partir de una hora especificada.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}

    log:CreateConsumerGroup(CreateConsumerGroup)

    Crea un grupo de consumidores en un logstore específico.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/${consumerGroupName}

    log:ListConsumerGroup(ListConsumerGroup)

    Enumera todos los grupos de consumidores de un logstore específico.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/*

    log:ConsumerGroupUpdateCheckPoint(UpdateCheckPoint)

    Actualiza el checkpoint de un shard para un grupo de consumidores específico.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/${consumerGroupName}

    log:ConsumerGroupHeartBeat(ConsumerGroupHeartBeat)

    Envía un latido (heartbeat) desde un consumidor específico al servidor.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/${consumerGroupName}

    log:UpdateConsumerGroup(UpdateConsumerGroup)

    Modifica las propiedades de un grupo de consumidores específico.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/${consumerGroupName}

    log:GetConsumerGroupCheckPoint(GetConsumerGroupCheckPoint)

    Obtiene el checkpoint de uno o de todos los shards de un grupo de consumidores específico.

    acs:log:${regionName}:${projectOwnerAliUid}:project/${projectName}/logstore/${LogStoreName}/consumergroup/${consumerGroupName}

    Para otorgar a un usuario de RAM los permisos que se detallan a continuación, utilice la siguiente directiva de ejemplo.

    • Identificador de cuenta de Alibaba Cloud: 174649****602745

    • Identificador de región: cn-hangzhou

    • Nombre del proyecto: project-test

    • Nombre del logstore: logstore-test

    • Nombre del grupo de consumidores: consumergroup-test

    Directiva de ejemplo:

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "log:GetCursorOrData"
          ],
          "Resource": "acs:log:cn-hangzhou:174649****602745:project/project-test/logstore/logstore-test"
        },
        {
          "Effect": "Allow",
          "Action": [
            "log:CreateConsumerGroup",
            "log:ListConsumerGroup"
          ],
          "Resource": "acs:log:cn-hangzhou:174649****602745:project/project-test/logstore/logstore-test/consumergroup/*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "log:ConsumerGroupUpdateCheckPoint",
            "log:ConsumerGroupHeartBeat",
            "log:UpdateConsumerGroup",
            "log:GetConsumerGroupCheckPoint"
          ],
          "Resource": "acs:log:cn-hangzhou:174649****602745:project/project-test/logstore/logstore-test/consumergroup/consumergroup-test"
        }
      ]
    }

    Como alternativa, puede adjuntar al usuario de RAM la directiva del sistema AliyunLogFullAccess, que otorga permisos para gestionar Simple Log Service. Esta directiva ya incluye todos los permisos que requieren las operaciones de los grupos de consumidores, por lo que no necesita crear una directiva personalizada.

  • Solución de problemas

    Para facilitar la solución de problemas, configure Log4j en su aplicación consumidora para registrar las excepciones del grupo de consumidores. A continuación se muestra un ejemplo de configuración de log4j.properties:

    log4j.rootLogger = info,stdout
    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target = System.out
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

    Después de configurar Log4j, la aplicación consumidora genera información de excepciones similar a la siguiente:

    [WARN ] 2018-03-14 12:01:52,747 method:com.aliyun.openservices.loghub.client.LogHubConsumer.sampleLogError(LogHubConsumer.java:159)
    com.aliyun.openservices.log.exception.LogException: Invalid loggroup count, (0,1000]
  • Consumir datos a partir de una hora específica

    // consumerStartTimeInSeconds indicates the time from which to start consuming data.
    public LogHubConfig(String consumerGroupName, 
                          String consumerName, 
                          String loghubEndPoint,
                          String project, String logStore,
                          String accessId, String accessKey,
                          int consumerStartTimeInSeconds);
    // position is an enumeration. LogHubConfig.ConsumePosition.BEGIN_CURSOR starts consumption from the oldest data. LogHubConfig.ConsumePosition.END_CURSOR starts consumption from the latest data.
    public LogHubConfig(String consumerGroupName, 
                          String consumerName, 
                          String loghubEndPoint,
                          String project, String logStore,
                          String accessId, String accessKey,
                          ConsumePosition position);
    Nota
    • Elija un constructor según sus necesidades.

    • Si ya existe un checkpoint guardado en el servidor, el consumo se reanuda desde ese punto.

    • Simple Log Service da prioridad a un checkpoint guardado para el consumo. Si especifica una hora de inicio, asegúrese de que el valor de consumerStartTimeInSeconds esté dentro del periodo de retención de datos (TTL). De lo contrario, se omite la hora de inicio especificada.

  • Restablecer un checkpoint

    public static void updateCheckpoint() throws Exception {
            Client client = new Client(host, accessId, accessKey);
            // The timestamp must be a UNIX timestamp in seconds. If your timestamp is in milliseconds, divide it by 1000.
            long timestamp = Timestamp.valueOf("2017-11-15 00:00:00").getTime() / 1000;
            ListShardResponse response = client.ListShard(new ListShardRequest(project, logStore));
            for (Shard shard : response.GetShards()) {
                int shardId = shard.GetShardId();
                String cursor = client.GetCursor(project, logStore, shardId, timestamp).GetCursor();
                client.UpdateCheckPoint(project, logStore, consumerGroup, shardId, cursor);
            }
        }

Referencias