/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed 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.
 */

package com.alibaba.nacos.client.logging.logback;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.core.CoreConstants;
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
import com.alibaba.nacos.common.utils.ResourceUtils;
import org.slf4j.impl.StaticLoggerBinder;

/**
 * Support for Logback version 1.0.8 or higher
 *
 * @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
 * @author <a href="mailto:hujun3@xiaomi.com">hujun</a>
 *
 * @since 0.9.0
 */
public class LogbackNacosLogging extends AbstractNacosLogging {
    
    private static final String NACOS_LOGBACK_LOCATION = "classpath:nacos-logback.xml";
    
    @Override
    public void loadConfiguration() {
        LoggerContext loggerContext = loadConfigurationOnStart();
        if (loggerContext.getObject(CoreConstants.RECONFIGURE_ON_CHANGE_TASK) != null) {
            addListener(loggerContext);
        }
    }
    
    private LoggerContext loadConfigurationOnStart() {
        String location = getLocation(NACOS_LOGBACK_LOCATION);
        try {
            LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
            NacosJoranConfigurator configurator = new NacosJoranConfigurator();
            configurator.setContext(loggerContext);
            configurator.doNacosConfigure(ResourceUtils.getResourceUrl(location));
            return loggerContext;
        } catch (Exception e) {
            throw new IllegalStateException("Could not initialize Logback Nacos logging from " + location, e);
        }
    }
    
    private void addListener(LoggerContext loggerContext) {
        loggerContext.addListener(new LoggerContextListener() {
            @Override
            public boolean isResetResistant() {
                return true;
            }
            
            @Override
            public void onReset(LoggerContext context) {
                loadConfigurationOnStart();
            }
            
            @Override
            public void onStart(LoggerContext context) {
            
            }
            
            @Override
            public void onStop(LoggerContext context) {
            
            }
            
            @Override
            public void onLevelChange(Logger logger, Level level) {
            
            }
        });
    }
    
}

@@ -1602,16 +1602,47 @@
  != null
+ && !hasListener(loggerContext)
 ) %7B%0A    
@@ -1685,36 +1685,356 @@
         %7D%0A    %7D%0A
+%0A
     
+private boolean hasListener(LoggerContext loggerContext) %7B%0A        for (LoggerContextListener loggerContextListener : loggerContext.getCopyOfListenerList()) %7B%0A            if (loggerContextListener instanceof NacosLoggerContextListener) %7B%0A                return true;%0A            %7D%0A        %7D%0A        return false;%0A    %7D%0A
 %0A    private Log
@@ -2674,110 +2674,56 @@
   %7D%0A
-    
 %0A    
-private void addListener(LoggerContext loggerContext) %7B%0A        loggerContext.addListener(new
+class NacosLoggerContextListener implements
  Log
@@ -2740,18 +2740,16 @@
 Listener
-()
  %7B%0A     
@@ -2743,36 +2743,32 @@
 tener %7B%0A        
-   
- 
 @Override%0A      
@@ -2753,36 +2753,32 @@
       @Override%0A
-    
         public b
@@ -2809,36 +2809,32 @@
 ) %7B%0A            
-    
 return true;%0A   
@@ -2838,39 +2838,19 @@
         
-    %7D%0A            %0A    
+%7D%0A%0A
         
@@ -2851,36 +2851,32 @@
       @Override%0A
-    
         public v
@@ -2904,36 +2904,32 @@
 text context) %7B%0A
-    
             load
@@ -2960,39 +2960,19 @@
         
-    %7D%0A            %0A    
+%7D%0A%0A
         
@@ -2981,36 +2981,32 @@
 verride%0A        
-  
-  
 public void onSt
@@ -3038,52 +3038,20 @@
 ) %7B%0A
-            %0A            %7D%0A            %0A    
+%0A        %7D%0A%0A
     
@@ -3056,36 +3056,32 @@
       @Override%0A
-    
         public v
@@ -3120,52 +3120,20 @@
 ) %7B%0A
-            %0A            %7D%0A            %0A    
+%0A        %7D%0A%0A
     
@@ -3142,28 +3142,24 @@
   @Override%0A
-    
         publ
@@ -3206,32 +3206,33 @@
 el level) %7B%0A
+%0A
         
     %0A       
@@ -3223,36 +3223,143 @@
     
+%7D%0A
     
+%7D%0A
 %0A    
-        %7D%0A        %7D
+private void addListener(LoggerContext loggerContext) %7B%0A        loggerContext.addListener(new NacosLoggerContextListener()
 );%0A 

Solve the problem of adding logback listener repeatedly. (#8454)