Android 开发者定位调整log缓冲区来解决丢log的问题

https://blog.csdn.net/kc58236582/article/details/51506896

里面提到了开发者定位来调整缓冲区的逻辑,进而理了一下。

frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java

关键prop是persist.logd.size,平常我们可以在debug的时候设置这个prop,比如1000000(大约1MB),然后再重启logd,start logd_reinit.或者修改init.rc来在debug开关打开的时候来设置。

console:/ # getprop | grep logd                                                
[init.svc.logd]: [running]
[init.svc.logd-reinit]: [stopped]
[logd.logpersistd]: []
[logd.logpersistd.enable]: [true]
[persist.logd.logpersistd]: []
[persist.logd.size]: [1048576]
[ro.boottime.logd]: [14823168131]
[ro.boottime.logd-reinit]: [15467994381]
[ro.logd.size.stats]: [64K]
console:/ # start logd-reinit
console:/ # [153290.668414@0] logd.daemon: reinit

下面是逻辑

这个类实现了OnPreferenceChangeListener接口,需要实现onPreferenceChange方法。这个方法会在每次变更Preference Screen时都会调用到。

public abstract class AbstractLogdSizePreferenceController extends
        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener

比如

    public void setTitle(CharSequence title) {
        if (title == null && mTitle != null || title != null && !title.equals(mTitle)) {
            mTitleRes = 0;
            mTitle = title;
            notifyChanged();
        }
    }

notifiyChanged就会调用回调

    /**
     * Should be called when the data of this {@link Preference} has changed.
     */
    protected void notifyChanged() {
        if (mListener != null) {
            mListener.onPreferenceChange(this);
        }
    }

这样在选择某个新的缓冲区的值之后,比如1M

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (preference == mLogdSize) {
            writeLogdSizeOption(newValue);
            return true;
        } else {
            return false;
        }
    }
    public void writeLogdSizeOption(Object newValue) {
        boolean disable = (newValue != null) &&
                (newValue.toString().equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE));
        String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
        if (currentTag == null) {
            currentTag = "";
        }
        // filter clean and unstack all references to our setting
        String newTag = currentTag.replaceAll(
                ",+" + SELECT_LOGD_TAG_SILENCE, "").replaceFirst(
                "^" + SELECT_LOGD_TAG_SILENCE + ",*", "").replaceAll(
                ",+", ",").replaceFirst(
                ",+$", "");
        if (disable) {
            newValue = SELECT_LOGD_MINIMUM_SIZE_VALUE;
            // Make sure snet_event_log get through first, but do not override
            String snetValue = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
            if ((snetValue == null) || (snetValue.length() == 0)) {
                snetValue = SystemProperties.get(SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY);
                if ((snetValue == null) || (snetValue.length() == 0)) {
                    SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, DEFAULT_SNET_TAG);
                }
            }
            // Silence all log sources, security logs notwithstanding
            if (newTag.length() != 0) {
                newTag = "," + newTag;
            }
            // Stack settings, stack to help preserve original value
            newTag = SELECT_LOGD_TAG_SILENCE + newTag;
        }
        if (!newTag.equals(currentTag)) {
            SystemProperties.set(SELECT_LOGD_TAG_PROPERTY, newTag);
        }
        String defaultValue = defaultLogdSizeValue();
        final String size = ((newValue != null) && (newValue.toString().length() != 0)) ?
                newValue.toString() : defaultValue;
        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, defaultValue.equals(size) ? "" : size);
        SystemProperties.set("ctl.start", "logd-reinit");
        SystemPropPoker.getInstance().poke();
        updateLogdSizeValues();
    }

SELECT_LOGD_SIZE_PROPERTY即是persist.logd.size, 写ctl.start为logd-reinit是要启动logd-reinit service,即重启logd。后面的日志删除就会根据这个prop来进行配置。缓冲区大了就会少丢日志。

    public static class PokerTask extends AsyncTask<Void, Void, Void> {

        @VisibleForTesting
        String[] listServices() {
            return ServiceManager.listServices();
        }

        @VisibleForTesting
        IBinder checkService(String service) {
            return ServiceManager.checkService(service);
        }

        @Override
        protected Void doInBackground(Void... params) {
            String[] services = listServices();
            if (services == null) {
                Log.e(TAG, "There are no services, how odd");
                return null;
            }
            for (String service : services) {
                IBinder obj = checkService(service);
                if (obj != null) {
                    Parcel data = Parcel.obtain();
                    try {
                        obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
                    } catch (RemoteException e) {
                        // Ignore
                    } catch (Exception e) {
                        Log.i(TAG, "Someone wrote a bad service '" + service
                                + "' that doesn't like to be poked", e);
                    }
                    data.recycle();
                }
            }
            return null;
        }
    }

 


 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值